useRef는 저장공간 또는 DOM요소에 접근하기 위해 사용되는 React Hook이다.
정의는 위와 같습니다.
저번글에서 우리는 useState를 통해 리렌더링이된다는 사실을 확인했고 왜 그런지도 알아봤습니다.
하지만 개발을 하다보면 렌더링을 막아야하는 경우도 생기게 됩니다.
그럴 때 사용하는 것이 useRef인데요.
useRef안의 값은 수정을 해도 렌더링이 되지 않습니다.
React에서 Component가 unmount될 때의 state를 딱 한번만 log를 찍고 싶을 경우 어떻게 해야할까요?
input값을 useState로 저장하는데 글자를 적을 때마다 렌더링이 된다. 이걸 막으려면 어떻게 해야하나요?
useRef를 알고 있다면 위 질문에 답을 할 수 있습니다.
useRef를 console로 찍어보면 current라는 값을 보여줍니다. 이제 이 값을 이용하여 useState와 비교해보도록 하겠습니다.
useRef 사용해보기
직접 코딩을 해서 useState와 useRef의 차이를 확인해보겠습니다.
useState로 count만들기
import { useState, useRef } from "react";
import reactLogo from "./assets/react.svg";
import "./App.css";
function App() {
const [count, setCount] = useState(0);
const increaseCount = () => {
setCount((value) => value + 1);
};
return (
<>
<p>{`CountState : ${count}`}</p>
<button onClick={increaseCount}>{`올림`}</button>
</>
);
}
export default App;
리액트를 사용하면 아시다시피 올림버튼을 누르면 count가 변경되면서 렌더링되어 화면에서 바뀐 count를 볼 수 있게 됩니다.
useRef로 count만들기
import { useState, useRef } from "react";
import reactLogo from "./assets/react.svg";
import "./App.css";
function App() {
const countRef = useRef(0);
const increaseCount = () => {
countRef.current += 1;
console.log(countRef.current);
};
return (
<>
<p>{`CountRef : ${countRef.current}`}</p>
<button onClick={increaseCount}>{`올림`}</button>
</>
);
}
export default App;
아무리 버튼을 눌러도 count는 변경되지 않습니다.
하지만 console창에선 바뀐 count가 버튼을 클릭할 때마다 출력되는 것을 확인할 수 있습니다.
위와 같은 현상은 useRef의 값이 변경되어도 컴포넌트가 렌더링 되지 않는 다는 것을 의미합니다.
그렇다면 한가지 의문이 생길 수 있습니다.
useRef를 사용하지 않고 var로 변수를 저장하면 useRef와 같은 기능을 보여주지 않을까?
위 질문에 대한 답은 아니오입니다.
렌더링을 한 후 두 값은 차이가 납니다.
useRef의 값을 변경한 후 렌더링 한 경우
import { useState, useRef } from "react";
import reactLogo from "./assets/react.svg";
import "./App.css";
function App() {
const countRef = useRef(0);
const [render, setRender] = useState(false);
const increaseCount = () => {
countRef.current += 1;
console.log(countRef.current);
};
const rendering = () => {
setRender((value) => !value);
};
return (
<>
<p>{`CountRef : ${countRef.current}`}</p>
<button onClick={increaseCount}>{`올림`}</button>
<button onClick={rendering}>{`렌더링`}</button>
</>
);
}
export default App;
렌더링을 의도적으로 구현했습니다.
useState는 값이 변경되면 렌더링이 되기 때문에 렌더링 버튼을 누르면 값(render)을 변하게 해서 렌더링 되도록 설계했습니다.
올림버튼을 5번 누른 후 렌더링 버튼을 누르니 useRef의 값이 잘 출력된 것을 확인할 수 있습니다.
var의 값을 수정한 후 렌더링한 경우
import { useState, useRef } from "react";
import reactLogo from "./assets/react.svg";
import "./App.css";
function App() {
var count = 0;
const [render, setRender] = useState(false);
const increaseCount = () => {
count += 1;
console.log(count);
};
const rendering = () => {
setRender((value) => !value);
};
return (
<>
<p>{`CountVar : ${count}`}</p>
<button onClick={increaseCount}>{`올림`}</button>
<button onClick={rendering}>{`렌더링`}</button>
</>
);
}
export default App;
올림을 여러번 누르고 렌더링 버튼을 눌렀을 때 countVar의 값이 변하지 않았습니다.
하지만 올림 버튼을 눌렀을 대 console창에서 값이 변한건 보이는군요.
왜 useRef는 렌더링했을 경우 잘 출력되지만
var로 저장했을 경우 렌더링을 했을 때 원하는 값이 출력되지 않았을까요?
그 이유는 렌더링이 될 경우 컴포넌트가 초기화 되기 때문입니다.
useRef와 다르게 var값은 렌더링이 될 경우 값이 다시 0으로 초기화 되게 됩니다.
function App() {
var count = 0;
const [render, setRender] = useState(false);
const increaseCount = () => {
count += 1;
console.log(count);
};
const rendering = () => {
setRender((value) => !value);
};
return (
<>
<p>{`CountVar : ${count}`}</p>
<button onClick={increaseCount}>{`올림`}</button>
<button onClick={rendering}>{`렌더링`}</button>
</>
);
}
이유는 위 코드에서 처럼 우리가 var count=0이 되도록 선언했기 때문이죠
렌더링이 되지 않았을 경우 count값이 잘 올라갔지만 렌더링이 되면서 count값이 다시 0이 되어 CountVar값이 0에서 변경되지 않았던 것입니다.
useRef를 활용하면 불필요한 렌더링을 줄일 수 있어 효율적인 웹사이트를 만들 수 있습니다.
'React js' 카테고리의 다른 글
Redux toolkits을 사용해 효과적으로 전역상태를 관리하자 (0) | 2023.05.02 |
---|---|
useEffect란 무엇이고 어떻게 사용하는 걸까? (0) | 2023.02.05 |
리액트에서 이벤트 버블링 체험하기 (0) | 2023.01.05 |
react에서 setInterval 사용하기 (0) | 2022.12.21 |
React + axios를 사용하여 공공데이터 휴일 호출하고 출력하기 (feat.postman) (0) | 2022.12.06 |