ref는 state처럼 저장하는 개념이다.
function TodoList() {
const [count, setCount] = useState(0);
console.log('렌더링중..');
const increaseCountState = () => {
setCount(count + 1);
};
return (
<div>
<p>State: {count}</p>
<button onClick={increaseCountState}>State 올려</button>
</div>
);
}
위 코드를 실행해 콘솔을 확인해보면 버튼을 누를때마다 렌더링이 된다.
반면 ref는 렌더링이 일어나지 않기에 겉으로 봤을땐 아무런 일이 일어나지 않는 걸로 보인다.
function TodoList() {
const [count, setCount] = useState(0);
const countRef = useRef(0);
console.log("렌더링...");
console.log(countRef);
const increaseCountState = () => {
setCount(count + 1);
};
const increaseRefState = () => {
countRef.current = countRef.current + 1;
};
return (
<div>
<p>State: {count}</p>
<p>Ref: {countRef.current}</p>
<button onClick={increaseCountState}>State 올려</button>
<button onClick={increaseRefState}>Ref 올려</button>
</div>
);
}
하지만 다시 state버튼을 누르면 렌더링이 되므로 Ref가
6으로 바뀐 것을 확인 할 수 있다!
콘솔에선 ref값이 바뀌고 있는지 확인해보자.
const increaseRefState = () => {
countRef.current = countRef.current + 1;
console.log("Ref: ", countRef.current);
};
짠! 화면으론 렌더링되지 않지만 , 실제 Ref는 1씩 증가하고 있다.
따라서 ref는 state보다 성능적인 면에서 더 효율적이다!
또한 ref는 호출이 되어도 항상 값을 유지한다.
이때 useEffect를 실행해보면 무한 렌더링 루프에 빠지게 된다.. 오류 메시지 ㄷㄷ..
이럴때 useRef 기능이 돋보인다!!
function TodoList() {
const [count, setCount] = useState(1);
const renderCount = 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>
);
}
버튼을 누를때마다 setCount는 ref의 특징덕분에 화면 상에선 렌더링이 안되므로 무한 루프가 발생하지 않는다!
그래서 이렇게 useEffect랑 적절하게 조합가능해서 코드 짜면 괜찮지 않을까?? 싶다!!