1. useRef 개요
1-1) ref는 state와 비슷하게 어떤 값을 저장하는 저장공간으로 사용된다.
- state의 변화
- 렌더링O => 컴포넌트 내부 변수들 초기화 (원하지 않는 렌더링 때문에 곤란해질 때 가 있다.)
- Ref의 변화
- state의 변화
- 렌더링O => 그래도 Ref의 값은 유지된다.
1-2) DOM 요소에 접근하기 위해 사용되기도 한다.
const UseRef = () => {
const [count, setCount] = useState(0);
const countRef = useRef(0); // 컴포넌트가 계속해서 렌더링 되어도 컴포넌트가 언마운트 되기 전 까지는 값을 유지한다.
// 1. ref는 state와 비슷하게 어떤 값을 저장하는 저장공간으로 사용된다.
// state의 변화 => 렌더링 => 컴포넌트 내부 변수들 초기화 (원하지 않는 렌더링 때문에 곤란해질 때 가 있다.)
// Ref의 변화 => No렌더링 => 변수들의 값이 유지된다.
// state의 변화 => 렌더링 => 그래도 Ref의 값은 유지된다.
// 2. DOM 요소에 접근
const increaseCountState = () => {
setCount(count + 1); // state가 변경될 때마다 UseRef라는 컴포넌트가 다시 렌더링 된다.
};
const increaseCountRef = () => {
countRef.current = countRef.current + 1; // ref는 수정되어도 컴포넌트가 렌더링 되지 않는다.
console.log("Ref값 : ", countRef.current); // ref값은 올라가는게 보이지만 화면이 렌더링 되지 않기 때문에 화면에는 값이 그대로이다.
// ref를 쓰는 이유 => state로 값을 변경하면 state가 바뀔 때마다 렌더링 되기 때문에 성능상 좋지 않다.
};
console.log("렌더링");
return (
<div>
<h1>useRef1</h1>
<button onClick={increaseCountState}>state +</button>
<button onClick={increaseCountRef}>countRef +</button>
<div>state : {count}</div>
<div>useRef : {countRef.current}</div>
</div>
);
};
const UseRef2 = () => {
const [render, setRender] = useState(0);
const countRef = useRef(0); // ref는 렌더링이 되어도 값을 유지한다. (ref의 값은 컴포넌트의 전생애주기를 통해 유지가 된다.)
let countVar = 0; // 렌더링될 때마다 (함수가 불릴 때 마다) 0으로 초기화 된다.
const doRendering = () => {
setRender(render + 1);
};
const increaseRef = () => {
countRef.current = countRef.current + 1;
console.log("Ref :", countRef.current);
};
const increaseVar = () => {
countVar = countVar + 1;
console.log("Var :", countVar);
};
const consoleRefVar = () => {
console.log(`Ref : ${countRef.current} , var : ${countVar}`);
};
return (
<div>
<h1>useRef2</h1>
<p>Ref : {countRef.current}</p>
<p>var : {countVar}</p>
<button onClick={doRendering}>Rendering Button</button>
<button onClick={increaseRef}>Ref +</button>
<button onClick={increaseVar}>Var +</button>
<button onClick={consoleRefVar}>show in console</button>
</div>
);
const UseRef3 = () => {
const [count, setCount] = useState(1);
const refRenderCount = useRef(0);
// const [renderCount, setRenderCount] = useState(1);
useEffect(() => {
// console.log("렌더링");
// setRenderCount(renderCount + 1); // count를 올리면 UseRef3이 다시 불리게 되고 useEffect가 불린다. useEffect안에도 state를 업데이트하는 카운트가 있어서 무한 반복된다.
refRenderCount.current = refRenderCount.current + 1;
console.log("렌더링 수 : ", refRenderCount.current);
// useRef는 변화는 감지해야 하지만 그 변화가 렌더링을 발생시키면 안되는 어떤 값을 다룰 때 편리하다.
});
const increaseCount = () => {
setCount(count + 1);
};
return (
<div>
<h1>useRef3</h1>
<p>Count : {count}</p>
<button onClick={increaseCount}>count+</button>
</div>
);
};
2. 기능구현