본문 바로가기
React

React(92) useRef 알아보기 (공식문서 정리)

by 새발개발JA 2023. 2. 1.
반응형

 

 

요즘은 공식문서 읽기에 재미가 붙었다.

리액트 beta 공식문서를 통해 기본적인 훅들과 기능들을 다시한번 훑어보며 정리 중이다.

오늘은 useRef 에 대해서 읽어보았다. 그러다 추억의 포스팅도 발견했다.

2년 전쯤 정리했던 포스팅인데 정말 무지했음을 다시 한번 느꼈다. (화이팅🥲)

 

React(27) 리액트 훅 useRef 란

useRef를 사용하는 이유 자바스크립트에서 특정 DOM (태그)을 선택할 때 getElementById, querySelector 같은 DOM Selector 함수를 사용한다. 우리 리액트(특히 함수형 컴포넌트)에서는 특정 태그를 선택할 때 us

devbirdfeet.tistory.com

 


React(92) useRef 알아보기 (공식문서 정리)

 

 

 

 

useRef 는 렌더링이 필요하지 않은 값을 참조하기 위한 리액트 훅이다.

const ref = useRef(initialValue)
console.log(ref) // { current: initialValue }

 

useRef 는 항상 {오브젝트} 를 리턴한다.

오브젝트 안에는 current 라는 필드가 있고 저장하는 값은 모두 이곳에 담긴다.

(이 오브젝트의 구조는 고정이라 바꿀 수 없다.)

 

초기값(InitialValue)을 넣어줄 수 있고 첫 렌더시에만 값이 들어가며 그 다음 렌더를 할 때는 적용되지 않는 값이다.

 

 

useRef 는 DOM 노드들을 저장할 수 있고, 내장 메소드들을 사용할 수 있다.

초기값을 null 로 선언하고 해당 <태그안에 ref={nodeRef}> 이런 식으로 담아준다.

 

그럼 이제부터 DOM 호출을 할 수 있다.

예를 들어 nodeRef.current.focus() 이런식으로 포커스 등의 기능들을 사용 가능하다 :)

const nodeRef = useRef(null)
.
.
.
return (
  <div ref={nodeRef}>여기에요</div>
)

 

useRef 는  값이 변해도 렌더링을 하지 않는다.

useState 는 값이 변하게 되면 렌더링을 하지만

useRef 는 값이 변해도 렌더링을 하지 않는다.

 

그래서 값이 바뀌는 동작이 눈에 보이는 visibility 가 있는 용도로는 사용하지 말고

차라리 useState 를 사용하라고 공식문서에서는 권장하고 있다. 

(한마디로 컴포넌트 리턴값인  HTML태그에 값을 넣지말라는 것이다)

 

 

또한 렌더링할 동안 읽기(Read)와 쓰기(Write) 을 하지 말아야 한다.

리액트 컴포넌트는 pure function 을 기대하고 있다.

즉, 렌더링 후에 약속된 값들만 한방에 변경해야 하는데,

렌더링할 동안 useRef 값을 변경하게 되면 기대하는 값과 다른 값이 튀어 나올 수 있기 때문이다.

 

 

예제코드 살펴보기

예제코드를 살펴보자.

특정 시간마다 숫자값이 올라가고, 화면에 표기되는 컴포넌트가 있다.

이것을 useRef 와 useState  두가지를 사용하여 각각 구현해 보았다.

state 와 ref 변수의 차이는 무엇일까

 

 

예제 코드 - useRef 를 사용했을 때

 

화면에 보이는 값은 변하지 않는다. 렌더 시에만 변한다.

우리가 원하는 결과는 화면에서 1, 2, 3, 4, 이런식으로 값이 변하는 것이다.

하지만 실제로 렌더되는 1-2초 사이의 값까지만 변하고 렌더 후에는 변하지 않는다. 원하는 결과가 나오지 않는다.

  const A = () => {
    const renderRef = useRef(0);

    useEffect(() => {
      setInterval(() => {
	// useRef 를 사용하는 경우
        ref.current = ref.current + 1;
      }, 1);
    }, []);

    // 위에서 값을 변경한 useRef 를 useMemo 에 담아 보여준다면?
    const cash = useMemo(() => {
      return ref.current + '원';
    }, [ref.current]);		// 디펜던시에 담으면 값이 바뀔때마다 렌더가 잘 되지 않을까?

    return <div>{cash}</div>;   // 하지만 값이 그대로이다.
  };

 

 

예제 코드 - useState 를 사용했을 때

화면에 보이는 값이 변한다. 렌더 시에만 변한다.

우리가 원하는 결과는 화면에서 1, 2, 3, 4, 이런식으로 값이 변하는 것이다. 그리고 그대로 나온다.

그 이유는 state 값이 변할 때 부분렌더가 되기 때문이다. 화면에 보여주기에 아주 적당하다.

  const A = () => {
    const renderRef = useRef(0);
    const [renderState, setRenderState] = useState(0);

    useEffect(() => {
      setInterval(() => {
	// useState 의 값을 변경하는 경우
        setRenderState(prev => prev + 1);
      }, 1000);
    }, []);

    return <div>{renderState}</div>; // 너무 잘나온다
  };

 

 

 

 

 

ref:

 

useRef

A JavaScript library for building user interfaces

beta.reactjs.org

 

반응형

댓글