useRef는 주로 DOM 엘리먼트를 직접 조작하고 싶을 때 사용한다.
그것 외의 사용처는 없는 줄 알았는데 useInterval 게시글 보다가 알게됨. (velog.io/@jakeseo_me/%EB%B2%88%EC%97%AD-%EB%A6%AC%EC%95%A1%ED%8A%B8-%ED%9B%85%EC%8A%A4-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8%EC%97%90%EC%84%9C-setInterval-%EC%82%AC%EC%9A%A9-%EC%8B%9C%EC%9D%98-%EB%AC%B8%EC%A0%9C%EC%A0%90)
훅스에서 ref는 변환가능한 current 프로퍼티를 가지는 순수한 오브젝트를 반환한다.
리액트의 컴포넌트는 리렌더링시에 모든 변수를 삭제하고 다시 생성해서 할당시키기 때문에 로컬 변수를 업데이트하고 유지할 수 없다.
ref의 current공간은 리렌더링을 해도 그 전값이 유지가 된다.
state처럼 변경되고 유지가 되는 변수가 필요하지만 변경시에 리렌더링을 하고 싶지 않을때 useRef가 유용하다.
예시
import React, {useState, useEffect} from 'react'
function App() {
const [stateNum, setState] = useState(0)
const obj = {num: 0}
let num = 0
const onClickFunc = () => {
num += 1;
obj.num += 1;
setState(stateNum + 1)
}
return (
<div className="App">
<p>
stateNum : {stateNum}
</p>
<p>
obj.num : {obj.num}
</p>
<p>
local num : {num}
</p>
<button onClick={onClickFunc}>클릭</button>
</div>
);
}
export default App;
클릭 버튼을 누르면 stateNum, obj.num, 로컬변수 num이 +1씩 증가시킨다.
하지만 클릭하면 obj.num과 local num은 값이 변하지 않는다.
그 이유는 state가 리렌더링 될 때마다 값이 제거되고 새로 초기화값인 0으로 할당받기 때문이다.
useRef는 리렌더링이 되어도 제거되지 않는 공간을 제공한다.
이 공간에 값을 저장하고 current 프로퍼티로 꺼내는 방식으로 로컬변수처럼 사용할 수 있다.
import React, {useState, useEffect, useRef} from 'react'
function App() {
const [stateNum, setState] = useState(0)
const obj = {num: 0}
let num = 0
const refNum = useRef(0)
const onClickFunc = () => {
num += 1;
obj.num += 1;
refNum.current += 1
setState(stateNum + 1)
}
return (
<div className="App">
<p>
stateNum : {stateNum}
</p>
<p>
obj.num : {obj.num}
</p>
<p>
local num : {num}
</p>
<p>
useRef num : {refNum.current}
</p>
<button onClick={onClickFunc}>클릭</button>
</div>
);
}
export default App;
useRef의 변수는 잘 작동한다.
어느 경우에 이게 유용할까?
내 생각에 값이 업데이트 되고 그 값이 유지되어야 하긴 하지만 바뀔때마다 리렌더링될 필요는 없는 경우에 이걸 써먹으면 좋다.
예시
const onClickFunc = () => {
num += 1;
obj.num += 1;
refNum.current += 1
console.log(num, obj.num, refNum.current)
if(refNum.current % 5 === 0) setState(stateNum + 1)
}
위 코드의 온클릭 함수인데 클릭을 5의 배수로 할 경우에만 리렌더링 하고싶다면 refNum값을 업데이트 하다가 조건을 만족했을때 state를 수정하면 된다.
위 코드결과
리렌더링은 5, 10, 15일때 딱 세번된다.
로컬 변수들은 리렌더링시 값이 초기화 되어서 0부터 다시 시작하는 모습이지만 ref에 저장한 변수는 값이 유지되는 걸 확인할 수 있다.
'프로그래밍' 카테고리의 다른 글
안드로이드 에러 unexpected element <queries> found in <manifest> (0) | 2020.12.25 |
---|---|
개인용 RN 배포 매뉴얼 (0) | 2020.12.24 |
리액트 커스텀 훅 (0) | 2020.12.14 |
리액트 memo로 리렌더링 관리하기 (0) | 2020.12.13 |
리액트 에러 경계 (0) | 2020.12.08 |