문제: 육안으로는 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,
}));
}
}
문제: 타입 에러 발생
원인 : 해당 코드에서 타입이 예를 들면 보통 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에서 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);
}
기술적인 부분