[내일배움캠프 WIL] 13주차

Jaehyeon Ye·2023년 1월 28일
0

이번주를 돌아보며... 트러블 슈팅

Batch Update

문제: 육안으로는 input 컴포넌트에 아무것도 입력되는 것 같아보이지 않았고 콘솔값을 찍어보면 두번재 setState에 의해 한 글자씩만 입력이 되었다. 그리고 테스트를 위해 setState를 한번 실행하도록 두번째 setState를 주석처리하면 콘솔에는 업데이트 전 state가 출력이 된다.

원인: 비동기인 setState의 특성을 잘 몰랐고 같은 setState 함수가 붙어있을 때 묶어서 한번만 업데이트 되는 Batch Update에 의해 발생하였다.

(e: React.ChangeEvent<HTMLInputElement>) => {
         const currentPwdValue = e.target.value;
         setPwdRelatedValues({ ...pwdRelatedValues, currentPwd: currentPwdValue });
         if (!pwdRegex.test(currentPwdValue)) {
           setPwdRelatedValues({
             ...pwdRelatedValues,
             currentPwdObserver: '올바르지 않은 형식의 비밀번호입니다.',
             isCurrentPwd: false,
           });
         } else {
           setPwdRelatedValues({
             ...pwdRelatedValues,
             currentPwdObserver: '올바른 형식의 비밀번호입니다.',
             isCurrentPwd: true,
           });
         }
       },

해결: 이러한 문제점을 해결하기 위해 setState 함수를 ()=>({}) 형태의 함수형 업데이트 방식으로 변경하였고 기대하는 방향대로 input값 입력이 실행되었다.

//To-be
if (name === 'currentPwd') {
      const currentPwdValue = value;
      setPwdRelatedValues((prev) => ({
        ...prev,
        [name]: currentPwdValue,
      }));
      if (!pwdRegex.test(currentPwdValue)) {
        setPwdRelatedValues((prev) => ({
          ...prev,
          currentPwdObserver: '올바르지 않은 형식의 비밀번호입니다.',
          isCurrentPwd: false,
        }));
      } else {
        setPwdRelatedValues((prev) => ({
          ...prev,
          currentPwdObserver: '올바른 형식의 비밀번호입니다.',
          isCurrentPwd: true,
        }));
      }
    }

Narrowing

문제: 타입 에러 발생
원인 : 해당 코드에서 타입이 예를 들면 보통 string과 null을 동반하는 Union 타입인 경우가 많았는데 값으로 null 타입이 들어올 것을 고려하지 않아서 발생된 type 에러였다.

//As-is
const onChangeProfileImg = (e: React.ChangeEvent<HTMLInputElement>) => {
    const reader = new FileReader();
    reader.readAsDataURL(e.target.files[0]);
    reader.onloadend = (finishedEvent: ProgressEvent<FileReader>) => {
    const profileURL = finishedEvent.target?.result;
		setAttachment(profileURL);
    localStorage.setItem('profileURL', profileURL);
    };
  };

해결방법 : type을 string | null 이런 식으로 직접 지정해주는 방법도 있겠지만 if문을 통해 null 이 아닌 경우만 실행하도록 하는 narrowing을 통해 에러를 해결하였다.

const onChangeProfileImg = (e: React.ChangeEvent<HTMLInputElement>) => {
    const reader = new FileReader();
    if (e.target.files) {
      reader.readAsDataURL(e.target.files[0]);
    }
    reader.onloadend = (finishedEvent: ProgressEvent<FileReader>) => {
      const profileURL = finishedEvent.target?.result;
      if (typeof profileURL === 'string') {
        setAttachment(profileURL);
        localStorage.setItem('profileURL', profileURL);
      }
    };
  };

Firebase onAuthChangeState 함수 대채

문제: 새로고침 시 유저 최신 정보가 화면에 반영되지 않는 문제가 있어서 이를 해결할 방법을 고민하였고 이에 대해 firebase에서 User 상태 업데이트 관련하여 제공하는 함수인 onAuthChange를 useEffect와 함께 사용하는 사례를 우선 채택하여 적용해보았다. 새로고침을 했을 때 유저의 최신 정보가 반영되기는 했지만 새로고침 직후 반영되는 그 사이에 조금의 긴 깜빡임이 발생하였다.

원인: 정확히는 잘 모르겠지만 비동기 함수라 firebase와 통신하여 정보를 받아오는데 다소 시간이 소요되기 때문인 것 같다.

useEffect(() => {
    authService.onAuthStateChanged(() => {
      setInit(true);
    });
  }, [setInit]);

해결: onAuthChange와 useEffect를 사용하는 대신 localstorage와 sessionStorage를 이용하여 즉각 정보를 받아옴으로써 새로고침 업데이트 시 깜빡이는 문제를 해결하였다.

let userObj = sessionStorage.getItem(`firebase:authUser:${apiKey}:[DEFAULT]`);
  let userObjParsed;
  if (userObj) {
    userObjParsed = JSON.parse(userObj);
  }

앞으로 구현해보고 싶은 부분

  • localstorage를 이용한 자동 로그인
  • 드롭다운 메뉴 + 조건 검색
  • (만약 모바일 프로젝트라면) QR 또는 바코드 카메라로 찍어서 얻은 일련번호 같은 정보 활용
  • 공공 웹사이트에 주로 있는 자동 로그아웃
  • http status에 따른 화면 표현
  • 공유 기능
  • 좋아요 또는 북마크 기능
  • 친구 추가
  • 채팅 또는 DM 기능

기술적인 부분

  • 아토믹 디자인
  • useMutation을 활용한 구현
  • Recoil 또는 contextAPI 부분 활용하여 전역 상태 관리
profile
FE Developer

0개의 댓글