useState에서 변경한 값이 바로변경되지 않는 이유
React에서 useState의 상태 업데이트는 비동기로 처리된다.
따라서 리렌더링을 완료하지않은경우 이전값을 가져오는 경우가 발생할 수 있어 주의가 필요하다.
반면 useRef는 값이 바뀌더라도 리렌더링과 관계없이 바로 참조할 수 있는 최신 값을 유지할 수 있다. 단순한 값의 저장 및 참조만 필요한 상황에서는 useRef를 고려하면좋다.
useState를 사용하면서 상태 업데이트의 비동기 특성까지 고려하고싶다면, useEffect나 콜백함수 내부에서 상태를 참조하는 방식으로 수정 할 수있다. 의존성으로 추가하여 상태 변화 시 최신값을 참조하도록 한다.
// useRef 대신 useState 사용
const [listCount, setListCount] = useState(0);
useEffect(() => {
if (dataCsIntegration) {
let newRowData = [];
newRowData = dataCsIntegration.items.map((item) => {
...
setListCount(dataCsIntegration.totalElements); // listCount 업데이트
}
}, [dataCsIntegration]);
const fetchAll = useCallback(async () => {
try {
// listCount를 함수 내부에서 참조
if (listCount > 1000) {
throw new Error('1000개 이상은 조회할 수 없습니다.');
}
const { data } = await apiClient.get(`...`, {
params: { ...searchOption, size: listCount } // 최신 listCount 사용
});
...
} catch (error) {
enqueueSnackbar(`${error.message}`, { variant: 'error' });
throw new Error(error);
}
}, [listCount]); // listCount 의존성 추가
fetchAll함수에서 listCount를 바로 참조하지 않고 useCallback에 listCount를 의존성으로 추가하여 최신값을 사용할 수 있도록하였다.
그러나 사실 해당 예제의 경우 listCount가 UI리렌더링과 관련없이 단순히 최신 값을 저장하고 사용하는 용도로만 쓰이고있기때문에 useRef를 사용하여 성능최적화를 유지(불필요한 리랜더링방지)하면서도 필요한 곳에 최신값을 바로 참조할 수 있다.
// useRef 대신 useState 사용
const listCount = useRef(0);
useEffect(() => {
if (dataCsIntegration) {
let newRowData = [];
newRowData = dataCsIntegration.items.map((item) => {
...
listCount.current = dataCsIntegration.totalElements; // listCount 업데이트
}
}, [dataCsIntegration]);
const fetchAll = useCallback(async () => {
try {
// listCount를 함수 내부에서 참조
if (listCount.current > 1000) {
throw new Error('1000개 이상은 조회할 수 없습니다.');
}
const { data } = await apiClient.get(`...`, {
params: { ...searchOption, size: listCount.current } // 최신 listCount 사용
});
...
} catch (error) {
enqueueSnackbar(`${error.message}`, { variant: 'error' });
throw new Error(error);
}
}, []);
useRef를 사용할 때 주의할 점
useRef를 사용할 때 의존성배열에는 추가하지 않는 것이 좋다. 이미 최신 상태를 유지하기때문에 의존성배열에 추가하지않아도 그 값을 바로사용할 수 있고 의존성 배열에 추가할 경우 불필요한 리랜더링을 초래할 수 있다.
반응형
'Frontend > React' 카테고리의 다른 글
[Nextjs13 에러] Uncaught SyntaxError: "undefined" is not valid JSON (0) | 2023.09.19 |
---|---|
useCallback한 함수를 다시 useCallback으로 깜싸는이유 (0) | 2023.09.06 |
vite, typescript, react env 설정 (0) | 2023.09.05 |
React에서 .env-cmdrc 안먹을때 (0) | 2023.07.18 |
[env-cmd] 리액트 env 사용방법 (0) | 2023.06.26 |