Front-end/React

[React] useRef로 이전 state 얻는 법

helloyukyung 2022. 4. 8. 18:55
export default function Index() {
  const [count, setCount] = useState(0);

  const PrevCountRef = useRef();

  useEffect(() => {
    console.log("work");
    PrevCountRef.current = count;
  });

  const PrevCount = PrevCountRef.current;
  console.log(count, PrevCount);

  return (
    <div>
      <div> Now :{count} </div>
      <div> Before : {PrevCount}</div>

      <button onClick={() => setCount(count + 1)}> up </button>
    </div>
  );
}

프로젝트를 진행하면서 이전 state값을 알아야 하는 경우가 발생했다.
공식 문서에서는 위의 예제와 같이 알려주고 있었다.

function Counter() {
  const [count, setCount] = useState(0);
  const prevCount = usePrevious(count);
  return <h1>Now: {count}, before: {prevCount}</h1>;
}

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

커스텀 훅으로 만들 수도 있다. 나중에 usePrevious() 훅을 제공할 수도 있다고 한다.

직접 타이핑 해보며 이해가 된 부분을 정리해보려고 한다.

useRef()

useRef()는 ref객체를 반환하는데, 반환된 ref 객체는 컴포넌트의 전 생애주기를 통해 유지된다.
보통 ref()객체를 사용하는 이유는 DOM에 접근하여 사용하기 위함인데, 지금과 같이 어떤 가변 값을 저장할 때도 유용하게 사용할 수 있다.

 

useRef()를 사용해 Ref객체를 만든 뒤 이 객체를 선택하고 싶은 DOM의 ref값으로 설정해준다.
그러면 Ref 객체의 .current값은 내가 원하는 DOM을 가르키게 된다.

 

ref객체의 초기값은 useRef()의 인자다.
해당 초기값은 ref의 .current에 할당되며 ref.current를 통해 해당 값에 접근이 가능하다.

const ref = useRef('초기값')
ref // {current : '초기값'}

useEffect()

useEffect는 랜더링 된 후 실행된다.

(1) 첫 화면 (2) up클릭 후 (3) 실행 콘솔 

동작 순서

1. count 의 현재 상태는 0

2. ref객체의 초기값은 useRef()의 인자 undefined (useEffect는 아직 실행되지 않음)

3. 화면에 Now : 0 , Before :노출 (사진1) (rendering end)

4. useEffect가 실행되어 ref.current 값에 0이 할당된다.

 

5. onClick을 통해 count값이 1로 업데이트 되는 순간 리랜더링

6. 현재 ref.current의 값은 0이므로 Before : 0

7. 화면에 Now : 1 , Before :0 노출 (사진2) (rendering end)

8. useEffect가 실행되어 ref.current 값에 1이 할당된다.