useRef를 활용하여 stale closure를 해결해보자

2025. 5. 17. 22:46·Intern

주의: 정확하지 않은 서술이 있을 수 있습니다.

 

 

컴포넌트 A에서 버튼을 클릭하면 recoil state가 변경되고, Hook B의 useEffect의 의존성 배열에 해당 recoil state가 있어서 Hook B에서 동작이 수행되게 설계를 했었다.

하지만 Hook B에서 recoil state의 변경을 잘 감지하지 못하는 경우가 발생했고, 따라서 의도치 않게 작동이 되는 상황이 벌어졌다.


1. 왜 recoil state의 변경을 감지하지 못했을까?

  // Component A
  const [something, setSomething] = useRecoilState(somethingState);

  const handleItemClick = (e: React.MouseEvent) => {
        setSomething({A : newValue});
  }


  (...)

  <Button onClick={handleItemClick />


  // Hook B
  const something = useRecoilValue(somethingState);

  useEffect(() => {
      // do something with something
  }, [something])

위와 같이 구성된 상황에서, 가끔씩 Hook B는 Component A의 변경된 상태가 아닌 이전 상태를 인식했다.

왜냐하면 Recoil은 setSomething을 호출하면 상태 변경을 요청하는데, 이 상태 변경은 다음 렌더링 사이클에서 실제 반영한다.

하지만 이 때, Hook B의 useEffect는 이전 렌더링 시점의 클로저를 캡처할 수 있기 때문에 상태 변경이 안되는 경우가 발생한다.

→ 이 현상을 바로 stale closure라고 한다.


2. useRef를 통해서 최신 상태를 참조하자​

  const something = useRecoilValue(somethingState);
  const somethingRef = useRef(something);

  useEffect(() => {
    somethingRef.current = something;
  }, [something]);

   useEffect(() => {
      // do something with somethingRef.current
  }, [something])

한 파일에 의존성 배열이 같은 useEffect가 있을 때 위에 있는 useEffect부터 실행된다(주의: 100% 보장은 아니라고한다).

 

더 위에 있는 useEffect를 통해 새로운 something을 somethingRef.current에 저장하고, 두 번째 useEffect(즉, 기존의 useEffect)에서 somethingRef.current를 통해서 갱신된 something 값을 사용하면 오류없이 작동을 보장할 수 있다.

 

 

주의: useEffect를 사용하지 않고 somethingRef.current = something;을 적용하는게 더 정확하다는 의견이 있다. 왜냐하면 직접 할당을 하면 렌더링 때마다 somethingRef.current에 something을 할당하기 때문에 더 안전하기 때문이라고 한다.

저작자표시 비영리 변경금지 (새창열림)

'Intern' 카테고리의 다른 글

배경이 따라오는 메모장을 만들기 위해 contentEditable을 사용해보자  (0) 2025.04.19
모노레포에서 다른 프로젝트로 파일을 옮길 때 조심해야 할 점  (0) 2025.04.19
네이버 지도 api 사용 시 마커가 많을 때 최적화 후기  (1) 2025.03.15
'Intern' 카테고리의 다른 글
  • 배경이 따라오는 메모장을 만들기 위해 contentEditable을 사용해보자
  • 모노레포에서 다른 프로젝트로 파일을 옮길 때 조심해야 할 점
  • 네이버 지도 api 사용 시 마커가 많을 때 최적화 후기
퀵차분
퀵차분
웹 프론트엔드 개발자를 꿈꾸고 있습니다 :)
  • 퀵차분
    QC's Devlog
    퀵차분
  • 전체
    오늘
    어제
    • 분류 전체보기 (165)
      • Frontend (28)
        • HTML, CSS (7)
        • Javascript (3)
        • React (11)
        • Typescript (2)
        • Next.js (4)
      • Node.js (3)
      • Study (40)
        • Modern JS Deep Dive (13)
        • SQL (1)
        • Network (1)
        • 프롬프트 엔지니어링 (4)
        • 인공지능 (9)
        • 시스템프로그래밍 (11)
        • 선형대수학 (1)
      • Intern (4)
      • KUIT (20)
      • Algorithm (48)
        • Baekjoon(C++) (26)
        • Programmers(JavaScript) (22)
      • 우아한테크코스(프리코스) (4)
      • Project (7)
        • PROlog (4)
        • Nomadcoder (2)
      • 생각 (4)
      • Event (7)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    자바스크립트
    javascript
    리액트
    next.js
    typescript
    프론트엔드
    타입스크립트
    알고리즘
    시스템프로그래밍
    react
    프로그래머스
    오블완
    인공지능
    KUIT
    프롬프트 엔지니어링
    티스토리챌린지
    HTML
    프로그래머스 자바스크립트
    백준
    음악추천
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
퀵차분
useRef를 활용하여 stale closure를 해결해보자
상단으로

티스토리툴바