안녕하세요 주갬입니다.
회사에서 리액트로 프로젝트를 하고 있는데 캐시를 지우고 사이트를 열면 렌더링이 제대로 되지 않는 오류를 발견했습니다.
문제 상황)
렌더링에 문제가 발생한 hook은 다음과 같습니다.
const tk = useSelector(state => state.user.tk);
const uuid = useSelector(state => state.user.uuid);
const ogc = useSelector(state => state.user.ogc);
useEffect(() => {
var data = JSON.stringify({
"tk" : tk,
"uuid" : uuid,
"ogc" : ogc
});
var config = {
method: 'post',
url: ~~~~ ,
headers: {
'Content-Type': 'application/json'
},
data : data
};
axios(config)
.then( (response) => {
~~~~~~~~~~
})
.catch((error) => {
console.log(error);
});
}, []);
렌더링 전에 이 useEffect hook을 실행해서 api를 호출해 받은 response 값을 초기 화면에 뿌려줘야했습니다.
따라서 해당 array는 처음 마운트 되어 렌더링 될 때만 호출하여 저장하면 되는 것이였으므로 useEffect의 파라미터로 빈 배열 []를 활용했었습니다.
https://bamtory29.tistory.com/entry/Hooks-useEffect
문제는 요청 페이로드로 redux에 저장된 값을 보내줘야한다는 것이였습니다. 처음에는 별 생각없이 redux로 저장된 데이터를 useSelector로 가져와 넣어주었었지만 이렇게 하니
1. 캐시를 지우고 처음 띄우면 렌더링에 오류가 나고
2. 그 상태에서 한번 더 새로고침하면 렌더링이 문제 없이 되는 현상이 발생했습니다.
이러한 특징으로 유추해봤을 때 react lifecycle을 내가 제대로 이해하지 못하여 렌더링 순서에 문제가 생긴 것이라고 생각했습니다.
그래서 우선 useSelector의 호출 시점을 찾아보았습니다.
https://bgpark.tistory.com/124
결론적으로 useSelector는 함수 컴포넌트 렌더링 이후에 호출이 되는 함수였습니다. 그래서 useEffect로 렌더링 되기 전에 useSelector로 받아오는 값을 사용하려고 하니 값이 제대로 들어가지 않아 api를 post 할 때 오류가 나는 것이였죠.
(새로고침을 하면 됐던 이유는 useSelector 함수가 이미 실행된 상태기 때문에 값이 저장되어 있었기 때문인 것으로 보입니다. - 정확하지 않음)
해결)
문제를 알았으니 useEffect 업데이트 기능을 이용하여 해결을 해봐야겠다고 생각했습니다.
const tk = useSelector(state => state.user.tk);
const uuid = useSelector(state => state.user.uuid);
const ogc = useSelector(state => state.user.ogc);
useEffect(() => {
var data = JSON.stringify({
"tk" : tk,
"uuid" : uuid,
"ogc" : ogc
});
var config = {
method: 'post',
url: ~~~~ ,
headers: {
'Content-Type': 'application/json'
},
data : data
};
axios(config)
.then( (response) => {
~~~~~~~~~~
})
.catch((error) => {
console.log(error);
});
}, [ tk, uuid, ogc]);
이렇게 useEffect의 괄호[]안에 tk, uuid, ogc을 넣어주면 tk, uuid, ogc에 값이 update될 때마다 렌더링이 다시 됩니다. 그러면 마지막 값 update후에는 api에 데이터가 완전하게 전달이 될 것이고 제대로 된 response가 나올 것입니다. 최종적으로 그 response를 이용해 값을 뿌려주니 오류없이 원하는 대로 렌더링이 된 화면을 볼 수 있었습니다~!
간단한 팁이지만 React는 렌더링 주기를 확실히 신경써야겠다는 생각을 다시금 하게 되었습니다.
읽어주셔서 감사합니다!
'React' 카테고리의 다른 글
[최적화] React 프로젝트 최적화 - 1. 문제점 인식 (LightHouse) (0) | 2024.02.19 |
---|---|
[React-bootstrap] 모달창 닫기버튼 스타일이 깨지는 현상 (0) | 2023.11.21 |
[React-Select 라이브러리] 'label' 키 이름 안맞추고 원하는 키 이름으로 지정하는 방법 (0) | 2022.05.04 |