Todo_SignIn/SignUp

Yeonn·2023년 11월 15일
0

Project_Todo

목록 보기
2/4
post-thumbnail

home

메인페이지는 최대한 심플하게 작업했다.
배경 이미지 위에 로고와 캐치프레이즈, Sign in/ Sign up 버튼이 있다.
버튼에는 hover 시에 반투명한 배경 색상이 생기면서 폰트 색이 변경되도록 하였는데,
이때 transition을 부여해 부드러운 애니메이션 효과가 있도록 하였다.

  const [signIn, setSignIn] = useState(true);

메인 페이지는 전체 한번만 렌더링 되고, 오른쪽 박스 내부의 부분만 'signIn state' 를 활용하여 true일 경우 sign in, false일 경우 sign up 으로 교체되도록 하였다.



🖍️ interface Props{ }

interface 를 작성할 때 useState 의 'setState' 의 경우 작성에 주의가 필요했다 !

기본 형태의 type을 소괄호 안에 value: type 형식으로 작성하고 => void;를 작성해준다.

setBooleanState: (value: boolean) => void;
setObjectState: (value: { [key: string]: string }) => void;

🌱 sign up

inputValue 관리

input 값을 onChange를 통해 'inputValue state'에 저장한다.

const handleInput = (e: React.ChangeEvent<HTMLInputElement>) => {
    const name: string = e.target.name;
    const value: string = e.target.value;
    setInputValue({ ...inputValue, [name]: value });

    checkForm();
  };

이때 자바스크립트와는 달리 이벤트에도 타입을 지정해야했다. e: React.ChangeEvent<HTMLInputElement> 로 지정하도록 해서 any를 방지했다.
이벤트 핸들링을 위한 타입은 같은 onChange라고 해도 요소에 따라서도 타입이 바뀌기 때문에 필요할 때마다 해당 타입을 찾아 사용하도록 한다 !

유효성 검사

const checkForm = () => {
    if (!inputValue.email || !inputValue.email.includes("@")) {
      setErrorMessage((prev) => ({
        ...prev,
        email: "이메일 양식을 지켜주세요(@를 포함해주세요)",
      }));
      setErrorCheck(false);
    } else if (inputValue && inputValue.email.includes("@")) {
      setErrorMessage((prev) => ({ ...prev, email: "" }));
    }

유효성 검사는 필요한 조건에 충족하지 않을 경우 'errorMessage state'에 에러 문구를 추가하고, 충족할 경우 'errorMessage state'의 해당 key-value를 ''로 초기화 하도록 했다.

 if (Object.values(errorMessage).every((value) => value === "")) {
      setErrorCheck(true);
    }

모든 값이 '' 빈문자열 일 경우 상위 컴포넌트에서 prop 받은 'errorCheck'의 상태를 true로 변경하고 이 errorCheck의 상태를 조건으로 'true'일 경우에만 signIn 통신이 진행되도록 구현하였다.

<S.Input
        name={title}
        placeholder={placeholder}
        type={type}
        onChange={handleInput}
        onBlur={checkForm}
      ></S.Input>
      <S.Warning>{errorMessage[title]}</S.Warning>

렌더링 되는 부분의 코드인데 렌더링될 때 title을 활용하여 값을 사용하려 했더니, 타입에 'any' 지정으로 또 이슈가 생겼다... 동적으로 처리할 값이고, 이미 모든 key에 타입을 부여해뒀는데 어떻게 처리해야 하나 시간이 조금 걸렸다.

const [errorMessage, setErrorMessage] = useState<{
    email: string;
    password: string;
    nickname: string;
    [key: string]: string;
  }>({ email: " ", password: " ", nickname: " " });

[key: string]: string; 를 통해 기본 타입을 부여해 줌으로써 해결할 수 있었다.

💬onChange/onBlur

유효성 검사를 위한 부분을 처음에는 onChange로만 작성하였는데 테스트 시 메일 작성 중 자동완성 기능을 사용하니 검사 조건 '@'가 포함되어 있어도 인식하지 못하는 문제를 발견했다.

그래서 해당 함수를 input의 onChange에 걸려있는 input값 관리 함수 'handleInput' 안에 실행시켜줌으로써 작성과 동시에 실행될 수 있도록 하면서, 자동완성 기능 사용을 고려하여 onBlur에도 작성해 포커스가 사라졌을 때 한번 더 확인할 수 있도록 하였다.

🌿 success sign up

유효성 검사에 통과해 회원가입이 완료되면 성공을 알리는 모달이 발생한다.
확인 / 닫기 버튼을 누르면 자동으로 main page인 'sign in' 버튼이 있는 화면으로 전환된다.



🎉 sign in

🥳 sign in function

const signIn = async () => {
    try {
      const response = await fetch("https://dummyjson.com/auth/login", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          username: "kminchelle",
          password: "0lelplR",
        }),
      });
      if (!response.ok) {
        console.log("failed sign in!🥲");
      }

      const result = await response.json();
      setIsUser(result);
    } catch (error) {
      console.log("during sign in💀: ", error);
    }
  };

sign in 함수는 비동기와 에러 처리를 위하여 try를 활용해 보았다. user에 대한 부분은 BE 없이 진행되는 프로젝트 이기 때문에 더미 데이터를 활용하였다.

🚀 move to Todo

const goToTodo = () => {
    navigate("/todo");
    window.location.reload();
  };

  useEffect(() => {
    if (isUser && isUser.token) {
      goToTodo();
    }
  }, [isUser]);

로그인이 완료되면 회원으 데이터를 state에 저장하고 저장된 데이터의 token을 확인하여 token을 보유하고 있을 경우 페이지가 useNavigate Hook을 활용하여 전환될 수 있도록 하였다. 이때 이동에 대한 부분을 useEffect로 비동기 처리하고, 'isUser state'가 변경될 때를 추적할 수 있도록 하여, '로그인 통신이 완료되면', 'token'을 확인하도록 구현하였다.

check point !

  • interface Props
    setBoolean: (value: boolean) => void 형태 !
  • onChange / onBlur
  • Object.values().every()
  • typescript의 비동기/에러 처리: const signIn = async() => { try{ //...code } }
  • navigate와 useEffect를 활용하여 조건에 따른 화면 전환 처리

1개의 댓글

comment-user-thumbnail
2023년 11월 15일

감사합니다. 이런 정보를 나눠주셔서 좋아요.

답글 달기