티스토리 뷰

usePrevious

const usePrevious = value => {
    const ref = useRef();
    useEffect(() => {
        ref.current = value;
    })
    return ref.current;
}

react docs에 보면 이런 코드에 대한 힌트를 얻을 수 있다. 이 훅은 전(Previous) state나 props의 값을 저장한다. 하지만 이 코드가 어떻게 전 value를 저장하는 결과를 가져오는 것일까?

첫 번째 포인트는 ref 값의 변화는 re-render를 트리거하지 않는다는 점이다. 반면 state의 변화는 re-render를 일으킨다. 예를 들어

const Counter = () => {
    const ref = useRef(0);
    const [counter, setCounter] = useState(0);

    return (
        <>
            <button onClick={() => setCounter(counter + 1)}>state counter</button>
            <button onClick={() => { ref.current ref.current + 1 }}>ref counter</button>
            state couter value: {counter}
            ref counter value: {ref.current}
        </>
    )
}

이런 코드에서 아무리 ref counter의 버튼을 눌러서 값을 증가시켜도 ref value의 변화는 리렌더링을 일으키지 않으므로 화면에 보이는 값은 갱신되지 않는다. 만약 그 상태에서 state counter를 증가시키면 리렌더링이 일어나면서 ref counter 값 또한 갱신된다.

두 번째 포인트는, useEffect는 렌더링이 끝나면 트리거된다는 점이다.

즉, 초기값이 0인 카운터를 가정했을 때 이런 플로우로 실행된다.

  • 컴포넌트가 처음 마운트하면 렌더링이 끝나고 useEffect는 실행되고(2번째 포인트) 그 콜백에 의해서 ref.current는 초기값 0을 저장할 것이다.
  • 만약 state가 1로 증가하면, 다시 리렌더링이 되면서 변화된 상태값 1이 화면에 표시된다. 이 리렌더링이 될 당시 ref.current에 저장된 값은 아직 0 이다. 리렌더링이 끝나고 useEffect가 실행되면서 콜백에 의해 변화된 상태값 1을 저장한다. ref 값의 변화는 리렌더링을 일으키지 않으므로 ref.current가 1로 갱신돼도 화면에서는 아무런 변화가 나타나지 않는다.
  • 즉 state 변화 -> 화면에 리렌더링 (이때 ref value는 여전히 이 전값을 가리킴) -> 리렌더링 후 useEffect가 실행되며 ref.current값을 최신으로 갱신 -> 하지만 이는 리렌더링을 일으키지 않음 -> 반복...

Ref

https://www.developerway.com/posts/implementing-advanced-use-previous-hook

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함