Dom요소에 접근을 위해 사용이 되는 React hooks 이다.
Ref는 reference의 약자로 '참조'라는 뜻이며 참조한 값을 저장하고 있는 공간이다.
useState는 state값이 바뀌면 컴포넌트를 재렌더링 시킨다. 하지만 useRef 는 값이 아무리 변경되어도 컴포넌트를 재렌더링 시키지 않는다. 이게 바로 Ref의 유용한점이다.
왜냐면 ?
컴포넌트 재렌더링 -> 컴포넌트 내부의 변수 초기화, 함수 재실행 -> 원하지 않는 사이드 이펙트 발생, 성능 저하(불필요한 렌더링)
export default function TimeCheck() {
const [showTime, setShowTime] = useState(false);
const h1Ref = useRef(0);
const clickFunc = () => {
setShowTime(!showTime);
};
useEffect(() => {
const timer = setInterval(() => {
h1Ref.current++;
console.log(h1Ref.current);
}, 1000);
return () => {
clearInterval(timer);
};
}, []);
return (
<div>
<h1>{h1Ref.current}</h1>
<button onClick={clickFunc}>시간</button>
</div>
);
}
우선 useEffect로 컴포넌트가 렌더링 되면 1초씩 카운트 되는 함수를 만들었다.
보이기 버튼을 누르면 컴포넌트가 렌더링 되고 시간 버튼을 누르면 state값이 바뀌면서 재렌더링이 일어나고 카운트 된 초가 표시된다.
위에 코드는 useRef 훅을 사용해서 값을 저장하고 있는데 값이 바뀌는 1초마다 컴포넌트가 렌더링 되지 않는다.
const [count, setCount] = useState(0);
const countTimer = setInterval(() => {
setCount((prev) => prev + 1);
}, 1000);
<h1>{count}</h1>
count값은 1초마다 바뀌면서 재렌더링이 1초마다 발생한다.
내가 원하는 동작은 백그라운드에서 시간을 1초씩 카운트해주고 버튼을 눌렀을 때만 카운트 되는 시간을 표시하는 것이었는데 이것이 ref와 state의 차이점이다.
useRef에 대해 공부하면서 알게 된 코드가 있어서 기록하려고 남겨본다.
const [inputs, setInputs] = useState({
name: '',
nickname: ''
});
const nameInput = useRef();
const { name, nickname } = inputs; // 비구조화 할당을 통해 값 추출
const onChange = e => {
const { value, name } = e.target; // 우선 e.target 에서
name 과 value 를 추출
setInputs({
...inputs, // 기존의 input 객체를 복사한 뒤
[name]: value // name 키를 가진 값을 value 로 설정
});
};