[React] React Hooks(3) - useRef #1변수관리

최예린·2022년 8월 4일
0

React

목록 보기
3/19

useRef

const ref = useRef(value)

✔ 함수형 컴포넌트에서 useRef를 사용하면 ref 객체를 반환한다.

✔ 입력한 초기값은 ref 안에 있는 current에 저장된다.

✔ ref는 언제든 수정이 가능

ref.current = "hello"

✔ 컴포넌트의 전 생애주기에 거쳐 유지된다. 즉, 계속 렌더링 되어도 컴포넌트가 언마운트 되기 전까지 값이 유지된다.

용도

1. 저장공간

  • State의 변화 -> 렌더링⭕ -> 컴포넌트 내부 변수들 모두 다시 초기화
    -> 원하는 않는 렌더링이 생길 수 있다.
  • Ref의 변화 -> 렌더링❌ -> 변수들의 값이 유지됨
  • State의 변화 -> 렌더링 -> Ref의 값은 유지됨

2. DOM 요소에 접근


ex) 로그인 창에서 input 박스를 클릭하지않아도 자동으로 focus가 되어있다면 바로 키보드를 입력할 수 있다.

[예제1] 기본예제

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

const App = () => {
  const [count, setCount] = useState(0);
  const countRef = useRef(0);
  
  console.log('렌더링...');
  
  const increaseCountState = () => {
    setCount(count + 1);
  };
  
  const increaseCountRef = () => {
    countRef.current = countRef.current + 1;
    console.log('Ref: ', countRef.current);
  };
  
  return (
    <div>
    	<p>State: {count}</p>
		<p>Ref: {countRef.current}</p>
		<button onClick={increaseCountState}>State 올려</button>
		<button onClick={increaseCountRef}>Ref 올려</button>
  	</div>
  );
};

export default App;
  • 여기서 State 올려 버튼을 클릭하면 곧바로 화면에 있는 state값이 1 증가한다.
    state값이 변경되면 App 컴포넌트가 다시 불려지기 때문에 화면이 렌더링되어 변경된 것이 바로 화면에 반영된다.
  • 하지만 Ref 올려를 누르면 실제로 countRef 객체 내부의 current 값이 1씩 증가되지만 화면에 바로 변화가 나타나지는 않는다. 이때, 다시 state올려 버튼을 누르면 state가 1 증가된 후 화면이 리렌더링 되면서 변경된 ref의 값도 같이 화면에 반영된다.

그렇기때문에 굉장히 값이 자주 바뀌는 경우에는 useRef를 사용하면 좋습니다.

[예제2] Ref 와 변수의 차이점

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

const App = () => {
  const [renderer, setRenderer] = useState(0);
  const countRef = useRef(0); // Ref
  let countVar = 0; // 변수
  
  const doRendering = () => {
    // state값이 변하면 렌더링됨
    setRenderer(render + 1);
  };
  
  const increaseRef = () => {
    countRef.current = countRef.current + 1;
    console.log('Ref: ', countRef.current);
  };
  
  const increaseVar increaseRef () => {
    countVar = countVar + 1;
    console.log('Var: ', countVar);
  };
  
  const printResults = () => {
    console.log(`ref: ${countRef.current}, var: ${countVar}`};
  };
  
  return (
    <div>
		<p>Ref: {countRef.current}</p>
		<p>Var: {countVar}</p>
		<button onClick={doRendering}>렌더!</button>
		<button onClick={increaseRef}>Ref 올려</button>
		<button onClick={increaseVar}>Var 올려</button>
		<button onClick={printResults}>Ref Var 값 출력</button>
  	</div>
  );
};

export default App;

렌더링된다.
= App 내부의 함수들이 불린다.
= 함수가 불릴 때마다 변수들이 다시 초기화 된다.

  • countVar는 렌더링 될 때마다 0으로 초기화 된다.
  • 하지만 Ref는 컴포넌트의 전 생애주기 동안 유지되기때문에 이 점이 다르다.

[예제3] Ref가 유용한 상황

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

const App = () => {
  const [count, setCount] = useState(1);
  const [renderCount, setRenderCount] = useState(1);
  
  useEffect(() => {
        console.log('렌더링!');
	    setRenderCount(renderCount + 1);
  });
  
  return (
    <div>
		<p>Count: {count}</p>
		<button onClick={() => setCount(count + 1)}>올려</button>
  	</div>
  );
};

export default App;

렌더링 횟수를 알고 싶을 때 이렇게 코드를 짜면 무한루프가 발생한다.
count 값이 바뀔 때 useEffect가 실행되고 또 useEffect 내부의 renderCount값이 바뀌면서 또 useEffect가 실행되고.. 또 renderCount값이 바뀌고...

이럴때 Ref를 사용하면된다.

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

const App = () => {
  const [count, setCount] = useState(1);
  const rederCount = useRef(1);
  
  useEffect(() => {
    renderCount.current = renderCount.current + 1;
    console.log('렌더링 수: ', renderCount.current);
  });
  
  return (
    <div>
		<p>Count: {count}</p>
		<button onClick={() => setCount(count + 1)}>올려</button>
  	</div>
  );
};

export default App;

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

profile
경북대학교 글로벌소프트웨어융합전공/미디어아트연계전공

0개의 댓글