const ref = useRef(value)
✔ 함수형 컴포넌트에서 useRef를 사용하면 ref 객체를 반환한다.
✔ 입력한 초기값은 ref 안에 있는 current에 저장된다.
✔ ref는 언제든 수정이 가능
ref.current = "hello"
✔ 컴포넌트의 전 생애주기에 거쳐 유지된다. 즉, 계속 렌더링 되어도 컴포넌트가 언마운트 되기 전까지 값이 유지된다.
- State의 변화 -> 렌더링⭕ -> 컴포넌트 내부 변수들 모두 다시 초기화
-> 원하는 않는 렌더링이 생길 수 있다.- Ref의 변화 -> 렌더링❌ -> 변수들의 값이 유지됨
- State의 변화 -> 렌더링 -> Ref의 값은 유지됨
ex) 로그인 창에서 input 박스를 클릭하지않아도 자동으로 focus가 되어있다면 바로 키보드를 입력할 수 있다.
import React, { useState, useRef} from 'react';
const App = () => {
const [count, setCount] = useState(0);
const countRef = useRef(0);
console.log('렌더링...');
const increaseCountState = () => {
setCount(count + 1);
};
const increaseCountRef = () => {
countRef.current = countRef.current + 1;
console.log('Ref: ', countRef.current);
};
return (
<div>
<p>State: {count}</p>
<p>Ref: {countRef.current}</p>
<button onClick={increaseCountState}>State 올려</button>
<button onClick={increaseCountRef}>Ref 올려</button>
</div>
);
};
export default App;
그렇기때문에 굉장히 값이 자주 바뀌는 경우에는 useRef를 사용하면 좋습니다.
import React, { useState, useRef} from 'react';
const App = () => {
const [renderer, setRenderer] = useState(0);
const countRef = useRef(0); // Ref
let countVar = 0; // 변수
const doRendering = () => {
// state값이 변하면 렌더링됨
setRenderer(render + 1);
};
const increaseRef = () => {
countRef.current = countRef.current + 1;
console.log('Ref: ', countRef.current);
};
const increaseVar increaseRef () => {
countVar = countVar + 1;
console.log('Var: ', countVar);
};
const printResults = () => {
console.log(`ref: ${countRef.current}, var: ${countVar}`};
};
return (
<div>
<p>Ref: {countRef.current}</p>
<p>Var: {countVar}</p>
<button onClick={doRendering}>렌더!</button>
<button onClick={increaseRef}>Ref 올려</button>
<button onClick={increaseVar}>Var 올려</button>
<button onClick={printResults}>Ref Var 값 출력</button>
</div>
);
};
export default App;
렌더링된다.
= App 내부의 함수들이 불린다.
= 함수가 불릴 때마다 변수들이 다시 초기화 된다.
import React, { useState, useRef, useEffect } from 'react';
const App = () => {
const [count, setCount] = useState(1);
const [renderCount, setRenderCount] = useState(1);
useEffect(() => {
console.log('렌더링!');
setRenderCount(renderCount + 1);
});
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>올려</button>
</div>
);
};
export default App;
렌더링 횟수를 알고 싶을 때 이렇게 코드를 짜면 무한루프가 발생한다.
count 값이 바뀔 때 useEffect가 실행되고 또 useEffect 내부의 renderCount값이 바뀌면서 또 useEffect가 실행되고.. 또 renderCount값이 바뀌고...
이럴때 Ref를 사용하면된다.
import React, { useState, useRef, useEffect } from 'react';
const App = () => {
const [count, setCount] = useState(1);
const rederCount = 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>
);
};
export default App;
Ref는 변화는 감지해야하지만 변화가 렌더링을 발생시키지않아야하는 값을 다룰 때 사용한다.