요즘은 공식문서 읽기에 재미가 붙었다.
리액트 beta 공식문서를 통해 기본적인 훅들과 기능들을 다시한번 훑어보며 정리 중이다.
오늘은 useRef 에 대해서 읽어보았다. 그러다 추억의 포스팅도 발견했다.
2년 전쯤 정리했던 포스팅인데 정말 무지했음을 다시 한번 느꼈다. (화이팅🥲)
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:
'React' 카테고리의 다른 글
React(94) useState 알아보기 (공식문서정리) (0) | 2023.02.21 |
---|---|
React(93) TypeScript - 유사객체배열에서 원하는 값 사용하기 (0) | 2023.02.16 |
React(91) 탭 클릭시 지정 영역으로 스크롤 이동 / 스크롤시 해당 탭 자동선택 (0) | 2023.01.25 |
React(90) useEffect 알아보기 (공식문서 정리) (0) | 2023.01.19 |
React(89) 글 작성시간 계산함수 만들기 (몇분전/몇시간전/몇일전) (0) | 2022.12.28 |
댓글