useEffect는 컴포넌트가 렌더링된 직후 실행되는 훅이다.
그리고 보통 컴포넌트가 언마운트될 때 실행할 동작을 설정하기 위해 useEffect 안에서 Clean-up 함수를 호출한다.
useEffect(() => {
return () => console.log(state);
}, [])
Clean-up 함수는 리렌더링 직후 의존성 배열의 state 중 변경된 값이 있다면 클로저에 의해 이전 시점의 state를 기준으로 실행되는 함수이다.
의존성 배열에 state가 들어 있으면 두 가지 경우에 실행된다.
- 컴포넌트가 언마운트될 때
- 해당 state의 값이 변경될 때
Clean-up 함수에서 해당 state를 찍어 보면 state가 변경되기 직전의 값이 출력될 것이다. 아래 코드가 그 예시이다.
export const Test = () => {
const [name, setName] = useState<string>("doringri");
useEffect(() => {
return () => console.log(name); // 버튼이 클릭됐어도 'doringri'가 출력됨
}, [name]);
const changeName = () => {
setName("fish");
}
return (
<button onClick={changeName}>
이름 변경
</button>
)
}
만약 useEffect의 의존성 배열을 비워 놓는다면 컴포넌트가 언마운트될 때만 실행되기 때문에 setTimeout, setInterval을 초기화시키는 등 메모리 누수를 방지하는 여러 처리를 할 수가 있다.
위 코드에서 useEffect의 의존성 배열을 비워 놓는다면 그런 처리가 가능하다.
그런데, 여기서 컴포넌트가 언마운트될 때 이전 시점의 state가 아닌 현재 state 값을 가져오고 싶을 때가 있다.
이때 useRef를 사용한다.
useRef는 렌더링에 영향을 주지 않는 값을 참조할 때 쓰는 훅이다.
export const Test = () => {
const [name, setName] = useState<string>("doringri");
const nameRef = useRef<string>(name);
useEffect(() => {
nameRef.current = name;
}, [name]);
useEffect(() => {
return () => console.log(nameRef.current); // 버튼을 클릭했다면 언마운트 시 'fish' 출력
}, []);
const changeName = () => {
setName("fish");
}
return (
<button onClick={changeName}>
이름 변경
</button>
)
}
name이라는 state를 의존성 배열로 가지고 있는 useEffect를 이용하여 값이 변경될 때마다 nameRef의 current 값을 업데이트시켰고, 이것을 언마운트될 때 가져와서 현재 값을 가져올 수 있게 되었다.
이처럼 DOM을 조작하는 작업 이외에도 useRef를 유용하게 사용할 수 있었다.
'IT > React & Next.js' 카테고리의 다른 글
| [React] React Profiler로 성능을 측정해보자 (1) | 2024.11.28 |
|---|---|
| [React] React.memo를 사용해보자 (1) | 2024.11.27 |
| [React] useReducer 사용하기 (1) | 2024.10.29 |
| [React] Jotai 사용해보기 (1) | 2024.10.04 |
| [React] 상태 관리 라이브러리 비교 (0) | 2024.09.29 |