ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • component를 직접변경하는 경우의 오류해결
    REACT 2021. 12. 14. 21:58

    문제는 로그인 컴포넌트를 만드는 경우에 발생했다.

     

     

    //RunLogin.tsx
    
    const RunLogin = ({ id, passwd, setRunLogin, setFailedAlarm, offFailedAlarm }: RunLoginTypeProps) => {
      const { loading, data } = useQuery(GET_USER_INFO, {
        variables: {
          userId: id,
        },
      });
     
        if (!loading) {
          if (data.personByUserId === null) {
            /* console.log("존재하지 않는 아이디 입니다"); */
            setRunLogin(false);
          } else if (passwd !== data.personByUserId.password) {
            console.log("비밀번호가 틀렸습니다");
            setRunLogin(false);
          } else {
            console.log("로그인 성공");
          }
        }
     
    
      return <></>;
    };
    
    export default RunLogin;
    //LoginMain.tsx
    
    const LoginMain = ({login} :LoginMainTypeProps) => {
    
      return(
    	<>
    	<div className="buttonContainer">
      		<div className="d-grid gap-2">
         		<button onClick={login} className="loginButton btn btn-primary" type="button">
           			login
         		</button>
      		</div>
    	</div>
        </> 
      )
    
    }
    
    export default LoginMain;
    //Login.tsx
    
    const [runLogin, setRunLogin] = useState(false);
    const login = () => {
      setRunLogin(true);
    };
    
    return(
    	<>
          {runLogin && (
            <RunLogin
              id={id}
              passwd={passwd}
              setRunLogin={setRunLogin}
              setFailedAlarm={setFailedAlarm}
              offFailedAlarm = {offFailedAlarm}
            />
          )}
         </>
     )

    위에 컴포넌트는 리턴값이 없는, apollo로 서버와 통신하고

    보낸 쿼리에 로딩이 끝나면 얻어온 data와 비교해서 콘솔에 노출시키고 runLogin값을 false로 바꿔

    RunLogin컴포넌트를 비활성화 하는 기능이다.

    비활성화 하지않으면 컴포넌트는 켜져 있는 상태기 때문에 버튼을 누르지 않아도 로직이 실행된다.

     

    보통 로그인 기능을 만들땐 함수형으로 로직을 만들어서 모듈폴더에서 제어하곤 했는데

    위에선 useQuery Hook을 쓰기 위해 컴포넌트로 만들었다.

     

    작동시켜보면

    이런 불편한 녀석과 마주하게 된다...

     

    해석하자면 컴포넌트가 랜더링되는동안에 다른컴포넌트를 업데이트 할수 없다는뜻이다.

    이것만 놓고보면 기능은 잘만 되는데?? 왜 오류가?? 라고 생각할수 있지만

     

    RunLogin컴포넌트는 리턴하는게 없는 컴포넌트다.

    문제를 파악하려면 눈으로 볼수 있는 리턴값이 있으면 된다.

     

    리턴할것을 아무거나 넣어보면 리턴값이 나오다가

    바로 컴포넌트가 비활성화되어 사라지는데 다음 버튼클릭부턴 아무것도 보이지 않는다.

    로직상 누를때마다 깜빡거려야한다.

     

    return <><div className="test">sdfewef</div></>;
    
    /*
    //style
    
    .test{
        position: absolute;
        top:50%;
        left: 0;
    }
    */

    (잘 안보여서 위치를 중간쯤으로 두고 실험해봤다.

    동영상이 없어 아쉽지만 위에 상태에선 한번만 깜빡거리고 두번째부턴 아예 생성되지않는다

    element에서도 한번만 나오고 안나옴)

     

    리랜더링이 안되는것 즉 충돌이 일어나고 있다.

     

    이건 사실 아주 간단하게 해결할수 있는데

    렌더링시 한번만 작동하게 하면된다.

    useEffect(() => {
        if (!loading) {
          if (data.personByUserId === null) {
            /* console.log("존재하지 않는 아이디 입니다"); */
            setRunLogin(false);
          } else if (passwd !== data.personByUserId.password) {
            console.log("비밀번호가 틀렸습니다");
            setRunLogin(false);
          } else {
            console.log("로그인 성공");
          }
        }
      });
    
      return <><div className="test">sdfewef</div></>;

    deps는 꼭 빼줘야 한다. 저기에 []같이 빈배열 넣어주면 첫 마운트때에만 작동해서

    원하는 효과를 못본다.

     

    이런식으로 useEffect 훅으로 감싸주면 성공적으로 버튼을 누를때마다 test가 깜빡거린다.

    의도한 기능대로 잘 작동된다

    (element상에서도 버튼을 누를때마다 깜빡인다)

     

    이제 test를 삭제하고 작동시키면 처음에 기대한 반응도 나오고 오류도 사라졌다.

     

    'REACT' 카테고리의 다른 글

    react-router V6에서 route props전달하기  (0) 2021.12.16
Designed by Tistory.