Web/React

[React] useRef (useState와 비교)

동띵 2022. 12. 21. 16:38

useRef는 변화는 감지해야 하지만 렌더링을 발생시키지 않는 값을 다룰 때 사용한다.

이것은 current라는 key 값을 가진 객체를 반환하는데,
여기서 value의 초깃값은 useRef의 인자 값이다.

ref.current로 value 접근 가능

ref 객체 값은 수정이 가능하기 때문에
.current로 접근하여 언제든지 값을 수정할 수 있다.

그리고 반환된 ref 객체는 컴포넌트가 사라지기 전까지 유지된다.

 

useRef는 state와 비슷하게 값을 저장하는 저장공간으로 사용된다.

하지만 여기서 ref와 state의 차이는 렌더링 발생 유무이다.

 

state는 set 함수를 통해 값이 변화되면 렌더링이 되어 컴포넌트 내부 변수를 초기화한다.

반면 ref는 값이 변화되어도 렌더링이 되지 않아 변수들의 값이 유지되어 불필요한 값의 렌더링을 막을 수 있다.

또한 state 변화에 의해 렌더링이 되어 컴포넌트 내부 변수가 초기화되어도 ref 값은 유지된다.

그래서 변경 시 렌더링을 발생시키지 말아야 할 값들을 다룰 때 useRef를 사용한다.

import React, { useRef, useState } from 'react'

function App() {
  const [count, setCount] = useState(0);
  const ref = useRef(0);

  const onClickState = () => {
    setCount(count + 1);
    console.log("state 값 click")
  }

  const onClickRef = () => {
    ref.current = ref.current + 1;
    console.log(`ref 값 : ${ref.current}`);
  }

  return (
    <div>
      <p>State: {count}</p>
      <button onClick={onClickState}>state 값 +</button>
      <br/>
      <p>Ref: {ref.current}</p>
      <button onClick={onClickRef}>ref 값 +</button>
    </div>
  );
}

export default App;

위 코드를 실행하면 useState와 useRef의 차이를 알 수 있다.

state + 버튼을 누르면 setCount를 통해 count 값을 1 증가시키고, 
ref + 버튼을 누르면 .current로 해당 값에 접근해 1 증가시키는 코드를 작성했다.

그리고 return문에 해당 요소들을 출력하게 했다.

state + 버튼과 ref + 버튼을 3번씩 클릭했는데,
state 값은 화면에 출력되는 반면 ref 값은 반영되지 않은 것을 확인할 수 있다.

그 이유는 useRef는 값이 변화돼도 리렌더링이 발생하지 않기 때문이다.

 

렌더링이 돼야 코드를 다시 실행해 값을 반영하는데
렌더링 되지 않아 실질적인 ref.current 값은 3이 되었지만 ref 값이 변하지 않는 것처럼 보인다.

 

위 상태에서 state 값 + 버튼을 누르면 count 값이 변하면서 렌더링이 돼 화면에 출력되는 ref 값이 바뀐다.

 

ref를 state 값이 아닌 일반 변수와도 비교할 수 있다.

useRef는 렌더링되어도 값을 유지하지만, 
일반 변수는 렌더링되면 선언 시 할당된 값으로 초기화된다.

import React, { useRef, useState } from 'react'

function App() {
  let val = 0;
  const ref = useRef(0);
  const [click, setClick] = useState(0);

  const onClickVal = () => {
    val = val + 1;
    console.log(`val 값 : ${val}`);
  }

  const onClickRef = () => {
    ref.current = ref.current + 1;
    console.log(`ref 값 : ${ref.current}`);
  }

  const onClickRender = () => {
    setClick(click + 1);
    console.log("click render button");
  }

  return (
    <div>
      <p>Val: {val}</p>
      <button onClick={onClickVal}>val 값 +</button>
      <br/>
      <p>Ref: {ref.current}</p>
      <button onClick={onClickRef}>ref 값 +</button>
      <hr/>
      <button onClick={onClickRender}>렌더링</button>
    </div>
  );
}

export default App;

위 코드에서 val 값 + 버튼과 ref 값 + 버튼을 3번씩 누르면
콘솔에는 값이 변하지만 화면에는 출력되지 않는다.

렌더링 버튼을 눌러 렌더링을 해주면 ref 값만 변하는 것을 볼 수 있다.

다시  val 값 + 버튼과 ref 값 + 버튼을 누르면 ref 값은 유지되지만 val 값은 0으로 초기화된다.

렌더링 시 ref 값은 유지되지만, 컴포넌트 내부 변수는 초기화되기 때문이다.

 

따라서 useRef는 변화는 감지해야 하지만
그 변화가 렌더링을 발생시키면 안되는 값을 관리할 때 사용할 수 있다.


참고자료

 

'Web > React' 카테고리의 다른 글

[React] useMemo  (2) 2022.12.25
[React] useRef (실제 DOM 접근)  (0) 2022.12.23
[React] JSX 안에서 중첩 삼 항 연산자 사용하기  (0) 2022.11.17
[React] Radio Button 커스텀  (0) 2022.11.06
[React] Nested Routes  (0) 2022.10.13