원문 주소 : https://betterprogramming.pub/understanding-the-closure-trap-of-react-hooks-6c560c408cde
Understanding the Closure Trap of React Hooks
Digging into the classic problem
betterprogramming.pub
문제
import { useEffect, useState } from 'react';
export default function App() {
const [count, setCount] = useState(0);
useEffect(() => {
setInterval(() => {
setCount(count + 1);
}, 1500);
}, []);
useEffect(() => {
setInterval(() => {
console.log(count);
}, 1500);
}, []);
return <div>Hello world</div>;
}
위 간단한 앱에서 count를 증가시키면 어떻게 될까요?
아래와 같이 0만 찍힙니다.
이것이 클로저 트랩입니다.
분석
React 런타임의 컴포넌트는 무엇입니까?
- 컴포넌트는 실제로 파이버 노드입니다.
- 그리고 각 파이버 노드에는 memorizedState라는 속성이 있습니다. 이 친구는 링크드 리스트입니다.
- 컴포넌트의 각 Hook은 memorizedState 링크드 리스트의 노드에 해당하며 해당 노드에서 자신의 값에 액세스합니다.
위 3개의 훅은 memorizedState 링크드 리스트의 노드이며, 각자의 값을 갖고 있습니다.
단방향 링크드 리스트군요!
각 훅은 각자의 memorizedState에 접근하여 자신의 방식대로 로직을 수행합니다.
훅의 구현
훅은 두 가지 위상을 같습니다.
즉 훅은 mount 함수이거나, 업데이트 함수입니다.
(주 : 실행 될 때의 "상태"정보를 갖으며, 해당 상태 플래그는 총 두개입니다.)
아래는 useEffect의 구현입니다.
훅이 어떻게 의존성을 관리하나요?
우리는 훅의 deps 파라미터에 주목해야 합니다.
deps가 정의되지 않으면 undefined처럼 취급합니다.
그리고 새로운 deps가 전달되면, 이전 deps와 이것을 비교합니다.
동일하면 기존의 함수를 사용합니다.
그렇지 않으면 새로운 함수를 만듭니다.
두 deps가 같은지 판단하는 로직은 매우 간단합니다.
이전 deps가 null이면 false를 리턴합니다.
즉, 둘은 같지 않다는 것입니다.
그렇지 않으면 배열 내부를 비교합니다.
우리는 이제 3개의 결론을 얻을 수 있습니다.
- 1. deps 배열이 undefined거나 null이면, 항상 함수를 새로 만듭니다.
- 2. 빈 배열이면, 단 한번 마운트 시에민 실행합니다.
- 3. 그렇지 않으면 배열 내부의 요소들을 각각 비교합니다.
useMemo 및 useCallback도 같은 방식으로 deps를 처리합니다.
이제 우리는 두 가지를 알고 있습니다.
- useEffect와 같은 훅은 memorizedState를 통해 데이터를 접근합니다.
- 훅은 deps가 같은지 비교하여 콜백 실행 여부를 판단합니다.
클로저 트랩
다시 클로저 트랩 문제로 돌아와 봅시다. 우리는 코드를 아래와 같이 작성했습니다.
useEffect(() => {
const timer = setInterval(() => {
setCount(count + 1);
}, 500);
}, []);
useEffect(() => {
const timer = setInterval(() => {
console.log(count);
}, 500);
}, []);
실행해야 하는 이펙트는 HasEffect로 표시되며 나중에 실행됩니다.

최신 상태를 얻고 싶으면, fn이 매 렌더링 마다 한번씩 실행되도록 해야 합니다.
즉, 우리는 count를 의존성 배열에 제공해야 합니다.
useEffect(() => {
setInterval(() => {
setCount(count + 1);
}, 1500);
}, [count]);
useEffect(() => {
setInterval(() => {
console.log(count);
}, 1500);
}, [count]);
결론
더보기
https://tkdodo.eu/blog/hooks-dependencies-and-stale-closures
Hooks, Dependencies and Stale Closures
Let's demystify what stale closures are in combination with react hooks with the help of the analogy of taking a photo ...
tkdodo.eu
- 10 JavaScript Closure Challenges Explained With Diagrams
- A React Hooks Challenge for Senior React Developers
10 JavaScript Closure Challenges Explained With Diagrams
Cracking the interview questions
betterprogramming.pub
A React Hooks Challenge for Senior React Developers
Can you solve this problem?
betterprogramming.pub
'FrontEnd' 카테고리의 다른 글
Valtio의 프록시 상태관리가 어떻게 동작할까? (Vanila Part) (0) | 2022.07.18 |
---|---|
언제 리코일을 사용하는게 좋을까? (6) | 2022.07.17 |
리액트에 SOLID 원칙 적용하기 (0) | 2022.07.17 |
리액트 쿼리 : FAQ(자주 묻는 질문) (2) | 2022.07.17 |
프레이머 모션[framer motion] 기초 2부 : 레이아웃 애니메이션 (0) | 2022.07.16 |