코딩/위코드 코딩학습

[위코드] TIL(Today I am Learned) -(42)(api통신연결)

카슈밀 2020. 9. 3. 01:49
반응형

- 오늘 해야할 일

백엔드와 회원가입 연결하기

- 오늘 수정사항

필요없는 잔여 코드 삭제 및 import 순서 정리

- 오늘 진행사항

백엔드 회원가입 성공

정상적으로 페이지에서 넘어가는 것도 성공.

- 오늘의 코드

e.preventDefalut()

 

오늘 엄청나게 고생했다. 

왜냐하면 이상하게 진입이 엉뚱한 곳으로 가는 것이 아닌가?

파비콘이 문제인가?

처음엔 파비콘이 문제인가 했었다.

그런데 스택오버플로우를 보면 그게 문제가 아니라 다른 숨어있는게 문제라고 한다.

<FormTag
              action="."
              method="post"
              onsubmit="return check_form();"
              >

찾다보니 이게 문제였다. formtag는 제일 먼저 렌더하는데, 그로인해 엉뚱한 페이지로 날려버리는 것....

원래 사이트에서 클론을 진행하는데,

해당 자료가 있다보니 이거 뭔데 있는거지? 하면서 그냥 그대로 복사해서 만들었는데,

해당 문구를 지워야지하면서 까먹고 놔둔 것...

아무튼 이를 해결하고 보니 제대로 넘어가긴 하는데, 나의 코드에서 뭔가 res.message를 보는데, 읽히지가 않는다.

이렇게 console.log(res.message) 데이터도 정상적으로 읽히는데,

그 다음줄인 if(res.message === "값을 입력해주세요")에서 가면 못 읽는다...

짜증...

아무튼 이를 해결하기 위해서 다른 팀원들도 해당 내용을 봐주는데,

나만안되서 내 코드를 봐주는 동료의 코드를 죄다 복사해서 붙여넣으니 정상작동...

뭔가 내가 안되게 해놨나보다?  ¯ࡇ¯ 

그런거 있지 않은가? 코드 제대로 다 쳤는데, 작동안되서 다시 똑같이 치면 정상적으로 되는.... 그런 경우인거 같았다.

아무튼 이를 정상적으로 만들고, 다시 진행하는데,

이게 왠걸 코드 내에 e.preventDefalut()를 넣어야 정상적으로 다른페이지로 넘어가는것이 아닌가?

 

왜지???? 했는데, 같은 팀원의 답변이 있었다.

 

해당 코드가 form태그 안에 있어서 라는 이유였다.

팀원 曰 : "a태그랑 form 태그는 이벤트 발생 시 제일 먼저 reload 시켜서 그래요"

이벤트 발생시 제일 먼저 리로딩하니 이벤트보다 태그를 리로딩하는 게

먼저라 이것을 막기 위해 e.preventDefalut()를 선언해야한다고 하는 것으로 이해했다.

 

아무튼 한페이지 백엔드로 연동하는데 이고생하는 것보면 진짜 언제나 어려운 것 같다.

import React, { useState, useEffect } from "react";
import { Link, useHistory, withRouter } from "react-router-dom";
import styled from "styled-components";
import Nav from "../../Components/Nav/Nav";
import Footer from "../../Components/Footer/Footer";
import DatePicker from "react-datepicker";
import ReCAPTCHA from "react-google-recaptcha";
import moment from "moment";
import { RECAPCHA_KEY, SUBMIT_POINT, UNIV_LIST } from "../../config";
import { addMonths } from "date-fns";
import "react-datepicker/dist/react-datepicker.css";

function Signup() {
  const [data, setData] = useState();
  const [startDate, setStartDate] = useState(null);
  const [userInfo, setUserinfo] = useState({
    username: "",
    firstname: "",
    lastname: "",
    password: "",
    email: "",
    subscriber: "",
    usertype: "",
    expirationdate: "",
    department: "",
  });
  const [valid, setValid] = useState("normal");
  const [honest, setHonest] = useState("third");
  const [calendar, setCalendar] = useState("jan");

  const history = useHistory();

  //밸리데이션 확인용
  useEffect(() => {
    const isDetector = userInfo.username.length > 4;
    const isNomal = userInfo.username.length === 0;
    const isEmailDetector =
      userInfo.email.length > 4 && userInfo.email.includes("@");
    const isEmail = userInfo.email.length === 0;
    const isCalendarDetector = startDate === null;
    if (isEmailDetector) {
      setHonest("first");
    } else if (!isEmailDetector) {
      if (isEmail) {
        setHonest("third");
      } else {
        setHonest("second");
      }
    }
    if (isDetector) {
      setValid("correct");
    } else if (!isDetector) {
      if (isNomal) {
        setValid("normal");
      } else {
        setValid("valid");
      }
    }
    if (isCalendarDetector) {
      setCalendar("jan");
    } else {
      setCalendar("feb");
    }
  }, [userInfo, startDate, calendar]);

  //대학교, 유저타입 백엔드통신용
  useEffect(() => {
    fetch(UNIV_LIST)
      .then((res) => res.json())
      .then((res) => {
        setData(res);
      });
  }, []);

  // 인풋값 감지용
  const inputValuedetector = (e) => {
    const { name, value } = e.target;
    setUserinfo({ ...userInfo, [name]: value });
  };

  //리캡챠용
  const onChange = (value) => {
    console.log("Captcha value:", value);
  };

  const submitBtn = (e) => {
    const {
      username,
      firstname,
      lastname,
      password,
      email,
      subscriber,
      usertype,
      expirationdate,
      department,
    } = userInfo;
    e.preventDefault();
    fetch(SUBMIT_POINT, {
      method: "POST",
      body: JSON.stringify({
        username,
        firstname,
        lastname,
        password,
        email,
        subscriber,
        usertype,
        expirationdate,
        department,
      }),
    })
      .then((res) => res.json())
      .then((res) => {
        if (res.message === "회원가입이 완료되었습니다.") {
          alert("회원가입을 환영합니다");
          history.push("/signin");
        } else if (res.message === "중복된 이메일입니다.") {
          alert("중복된 이메일입니다.");
        } else if (res.message === "중복된 이메일입니다.") {
          alert("이메일과 비밀번호를 확인해주십시오");
        }
      });
  };

  return (
    <>
      <Nav />
      {/* 이제부터 바디내용 */}
      <div>
        <ContainerWrap>
          <InnerContent>
            <TitleContainer>
              <FirstTitle>Register for WRDS</FirstTitle>
            </TitleContainer>
            <BodyContainer>
              <FormTag>
                {/* 유저네임 */}
                <FormGroup>
                  <LabelName>Username</LabelName>
                  <InputGroup>
                    <InputValue
                      onChange={inputValuedetector}
                      type="text"
                      name="username"
                      maxlength="15"
                      placeholder="Username"
                      title="Required. 4 to 15 characters long. 
                    Lowercase letters and digits only. 
                    Must start with a letter."
                    />
                    <ValidationBox>
                      <SpanName valid={valid === "normal"}>
                        Please choose a username.
                      </SpanName>
                      <SpanName valid={valid === "valid"}>
                        The username you have entered is too short.
                      </SpanName>
                      <SpanName color="#5CB85C" valid={valid === "correct"}>
                        The username you have selected is available.
                      </SpanName>
                    </ValidationBox>
                  </InputGroup>
                  <SmallText>
                    Required. 4 to 15 characters long. Lowercase letters and
                    digits only. Must start with a letter.
                  </SmallText>
                </FormGroup>
                {/* 성 */}
                <FormGroup>
                  <LabelName type="id_first_name">First name</LabelName>
                  <InputValue
                    onChange={inputValuedetector}
                    type="text"
                    name="firstname"
                    maxlength="254"
                    placeholder="First name"
                  />
                </FormGroup>
                {/* 이름 */}
                <FormGroup>
                  <LabelName type="id_last_name">Last name</LabelName>
                  <InputValue
                    onChange={inputValuedetector}
                    type="text"
                    name="lastname"
                    maxlength="254"
                    placeholder="Last name"
                  />
                </FormGroup>
                <FormGroup>
                  <LabelName type="password">Password</LabelName>
                  <InputValue
                    onChange={inputValuedetector}
                    type="password"
                    name="password"
                    maxlength="254"
                    placeholder="password"
                  />
                </FormGroup>
                {/* 이메일 주소 */}
                <FormGroup>
                  <LabelName type="id_email">Email address</LabelName>
                  <InputGroup>
                    <InputValue
                      onChange={inputValuedetector}
                      type="email"
                      name="email"
                      maxlength="15"
                      placeholder="Email addresssername"
                    />
                    <ValidationBox>
                      <SpanName honest={honest === "third"}>
                        Please enter your institutional email address.
                      </SpanName>
                      <SpanName honest={honest === "second"}>
                        This is a valid email address. Please select your
                        institution below.
                      </SpanName>
                      <SpanName color="#5CB85C" honest={honest === "first"}>
                        This is a valid email address for the chosen subscriber.
                      </SpanName>
                    </ValidationBox>
                  </InputGroup>
                </FormGroup>
                {/* 대학교리스트 */}
                <FormGroup>
                  <LabelName>Subscriber</LabelName>
                  <select
                    onChange={inputValuedetector}
                    name="subscriber"
                    className="form-control"
                    id="id_subscriber"
                  >
                    {data &&
                      data.univ.map((el) => {
                        return (
                          <option key={el.id} value={el.id}>
                            {el.name}
                          </option>
                        );
                      })}
                  </select>
                </FormGroup>
                {/* 유저타입 */}
                <FormGroup>
                  <LabelName type="id_user_type">User type</LabelName>
                  <select
                    onChange={inputValuedetector}
                    name="usertype"
                    className="form-control"
                    title="The account type of this user."
                    id="user_type"
                  >
                    {data &&
                      data.type.map((el) => {
                        return (
                          <option key={el.id} value={el.id}>
                            {el.name}
                          </option>
                        );
                      })}
                  </select>
                  <SmallText>The account type of this user.</SmallText>
                </FormGroup>
                {/* 만료기간 */}
                <FormGroup>
                  <LabelName>Expiration date</LabelName>
                  <InputGroup>
                    <ValidationBox>
                      <SpanName calendar={calendar === "jan"}>
                        Please enter a valid expiration date (YYYY-MM-DD).
                      </SpanName>
                      <SpanName color="#5CB85C" calendar={calendar === "feb"}>
                        This is a valid expiration date.
                      </SpanName>
                    </ValidationBox>
                  </InputGroup>
                </FormGroup>
                {/* 부서 */}
                <FormGroup>
                  <LabelName type="id_department">Department</LabelName>
                  <InputValue
                    onChange={inputValuedetector}
                    type="text"
                    name="department"
                    maxlength="254"
                    placeholder="Department"
                  />
                </FormGroup>
                {/* 리캡차 */}
                <FormGroup>
                  <LabelName type="id_captcha">Captcha</LabelName>
                  <ReCAPTCHA sitekey={`${RECAPCHA_KEY}`} onChange={onChange} />
                </FormGroup>
                {/* 회원약관 */}
                <FormGroup>
                  <LabelName type="id_terms_of_use">Terms of Use</LabelName>
                  <AcceptContract>
                    By submitting this form, you accept the
                    <Link className="TermsLink" to="">
                      &nbsp;Terms of Use
                    </Link>
                  </AcceptContract>
                </FormGroup>
                <SubmitBTN type="submit" onClick={submitBtn}>
                  &nbsp;Register for WRDS
                </SubmitBTN>
              </FormTag>
              <DatePicker
                className="calenderposition"
                selected={startDate}
                dateFormat="yyyy-MM-dd"
                onChange={(date) => {
                  setStartDate(date);
                  setUserinfo({
                    ...userInfo,
                    expirationdate: moment(date).format("YYYY-MM-DD"),
                  });
                }}
                minDate={addMonths(new Date(), 6)}
                maxDate={addMonths(new Date(), 12)}
                onKeyDown={(e) => e.preventDefault()}
                type="text"
                name="expiration_date"
                placeholderText=" Expiration date"
              />
            </BodyContainer>
          </InnerContent>
        </ContainerWrap>
      </div>
      <Footer />
    </>
  );
}

export default withRouter(Signup);

// 회원가입창 내용
const ContainerWrap = styled.div`
  width: 100%;
  max-width: 1170px;
  margin: 0 auto;
  padding: 0 auto;
`;
const InnerContent = styled.div`
  display: flex;
  flex-wrap: wrap;
  margin-right: -15px;
  margin-left: -15px;
`;

//Resister for RDS 감싼 부분.
const TitleContainer = styled.div`
  flex: 0 0 100%;
  max-width: 100%;
`;
const FirstTitle = styled.h1`
  border-bottom: 1px solid #dddddd;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  padding-bottom: 11.5px;
  margin: 15px 0px 15px 0px;
  font-size: 2.5rem;
  font-weight: 500;
  line-height: 1.2;
`;

// 아이디 비밀번호 입력하는 내용 부분.
const BodyContainer = styled.div`
  position: relative;
  flex: 0 0 100%;
  max-width: 100%;
  width: 100%;
  padding-right: 15px;
  padding-left: 15px;

  .calenderposition {
    background: #fff
      url(https://code.jquery.com/ui/1.10.3/themes/smoothness/images/ui-bg_flat_75_ffffff_40x100.png)
      50% 50% repeat-x;
    color: #222222;
    position: absolute;
    display: block;
    border: 1px solid #ced4da;
    width: 17em;
    padding: 0.2em 0.2em 0;
    min-height: 0;
    bottom: 339px;
    width: 1138px;
    height: 36px;
    border-radius: 0.25rem;
    font-size: 1rem;
    font-weight: 400;
    line-height: 1.5;
  }

  .react-datepicker-popper {
    top: -349px !important;
  }
  .react-datepicker__triangle {
    display: none;
  }
`;

// 폼 양식인 부분.
const FormTag = styled.form`
  margin-top: 0em;
`;
const FormGroup = styled.div`
  margin-bottom: 1rem;

  .form-control {
    display: block;
    color: #495057;
    background-color: #fff;
    background-clip: padding-box;
    border: 1px solid #ced4da;
    width: 100%;
    height: calc(1.5em + 0.75rem + 2px);
    padding: 0.375rem 0.75rem;
    font-size: 1rem;
    font-weight: 400;
    line-height: 1.5;
    border-radius: 0.25rem;
    box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
    transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
  }
`;
const LabelName = styled.label`
  display: inline-block;
  margin-bottom: 0.5rem;
`;

const InputGroup = styled.div`
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  justify-content: flex-end;
  width: 100%;
`;
const InputValue = styled.input`
  position: relative;
  color: #495057;
  background-color: #fff;
  background-clip: padding-box;
  border: 1px solid #ced4da;
  display: block;
  flex: 1 1 0%;
  min-width: 0;
  margin-bottom: 0;
  width: 100%;
  height: calc(1.5em + 0.75rem + 2px);
  padding: 0.375rem 0.75rem;
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.5;
  border-radius: 0.25rem;
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
`;
const ValidationBox = styled.div`
  display: flex;
  margin-left: -1px;
`;

// username 밸리데이션
const SpanName = styled.span`
  color: #fff;
  background-color: ${(props) => props.color || "#c5093b"};
  border-color: ${(props) => props.color || "#c5093b"};
  display: ${(props) =>
    props.valid || props.honest || props.calendar ? "block" : "none"};
  align-items: center;
  text-align: center;
  white-space: nowrap;
  border: 1px solid #ced4da;
  padding: 0.375rem 0.75rem;
  margin-bottom: 0;
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.5;
  border-radius: 0.25rem;
  z-index: 5;
`;

// 인풋창 아래에 있는 작은 글씨들
const SmallText = styled.small`
  color: #6c757d;
  margin-top: 0.25rem;
  font-size: 80%;
  font-weight: 400;
`;

//계약서 동의문구
const AcceptContract = styled.h5`
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  margin-bottom: 0.5rem;
  font-weight: 500;
  line-height: 1.2;
  font-size: 1.25rem;
  margin-top: 0;

  .TermsLink {
    color: #004785;
    text-decoration: none;
    background-color: transparent;

    &:hover {
      text-decoration: underline;
    }
  }
`;

// 제출 버튼
const SubmitBTN = styled.button`
  cursor: pointer;
  color: #fff;
  background-color: #004785;
  border-color: #004785;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15),
    0 1px 1px rgba(0, 0, 0, 0);
  font-weight: 400;
  text-align: center;
  vertical-align: middle;
  border: 1px solid transparent;
  transition: color 0.15s ease-in-out;
  padding: 0.5rem 1rem;
  font-size: 1.25rem;
  line-height: 1.5;
`;
728x90