useRef는 렌더링에 필요하지 않는 값을 참조할 수 있는 React Hook입니다.
렌더링이 잦게 되면 리액트의 성능에 문제가 생길 수 있기 때문에, 렌더링이 될 props, state와 렌더링이 되지 않을 값을 구분하는 것은 매우 중요한 일이다.
const ref = useRef(initialValue)
공식 문서에 따르면 ref는 위와같이 사용될 수 있다.
ref.current 프로퍼티를 변경해도 React는 컴포넌트를 다시 렌더링하지 않습니다. ref는 일반 자바스크립트 객체이기 때문에 React는 사용자가 언제 변경했는지 알지 못합니다. 초기화를 제외하고는 렌더링 중에 ref.current를 쓰거나 읽지 않는 것으로 합쉬다.
● useRef 사용법 : 클릭카운터
const App = ()=>{
let ref = useRef(0);
const handleClick = ()=>{
ref.current = ref.current + 1;
alert(`you clicked ${ref.current} times!`)
}
return (
<button onClick={handleClick}>Click me</button>
)
}
렌더링 될 필요가 없는 부분을 ref부분으로 빼서 만들엇움니다.
● useRef 사용법 : 스톱워치
const App = ()=>{
const [startTime, setStartTime] = useState(null);
const [now, setNow] = useState(null);
const intervalRef = useRef(null);
function handleStart() {
setStartTime(Date.now());
setNow(Date.now());
clearInterval(intervalRef.current);
intervalRef.current = setInterval(() => {
setNow(Date.now());
}, 10);
}
function handleStop() {
clearInterval(intervalRef.current);
}
let secondsPassed = 0;
if (startTime != null && now != null) {
secondsPassed = (now - startTime) / 1000;
}
return (
<>
<h1>Time passed: {secondsPassed.toFixed(3)}</h1>
<button onClick={handleStart}>
Start
</button>
<button onClick={handleStop}>
Stop
</button>
</>
);
}
● useRef 사용법 : DOM 조작
실질적으로 DOM에 접근하면 불필요하게 렌더링을 하거나 virtual DOM의 성능에 오류가 생길 수 있기 때문에 리액트에서는 DOM에 직접적으로 DOM에 접근하지 않는다. 따라서 ref를 사용해 접근함여
const App = ()=>{
const inputRef = useRef(null);
const handleFocus = ()=>{
inputRef.current.focus()
}
return(
<div>
<input type='text' ref={inputRef}/>
<button onClick={handleFocus}>누르면 인풋에 포커싱</button>
</div>
)
}
비디오 틀기 ㅋ
const App = ()=>{
const [isPlaying, setIsPlaying] = useState(false);
const ref = useRef(null);
const handleClick = ()=>{
const nextIsPlaying = !isPlaying;
setIsPlaying(nextIsPlaying);
if (nextIsPlaying) {
ref.current.play();
} else {
ref.current.pause();
}
}
return(
<div>
<button onClick={handleClick}>{isPlaying ? 'Pause' : 'Play'}</button>
<video
width="250"
ref={ref}
onPlay={() => setIsPlaying(true)}
onPause={() => setIsPlaying(false)}
>
<source
src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
type="video/mp4"
/>
</video>
</div>
)
}
● useRef 사용법 : 부모컴포넌트에서 자식컴포넌트로 ref 넘겨주기
아니 자꾸 아래 처럼 부모컴포넌트에서 자식 컴포넌트로 ref를 넘겨주려하니 troubleShooting이 있더군요..
그런데 소름돋는 공식문서에 적혀있는 .. 해결법
App.js
function App() {
const inputRef = useRef();
function handleClick() {
inputRef.current.focus();
}
return (
<>
<Child ref={inputRef} />
<button onClick={handleClick}>
Focus the input
</button>
</>
);
}
Child.js
const Child = ({ref}) => {
return <input type="text" ref={ref} />;
};
부모 컴포넌트에서 자식컴포넌트로 ref를 props로 전달하려고 했는데 자꾸 오류가 뜨덥니다..
하지만 자식 컴포넌트에 forwarRef로 감싸주면 해결되는 일이 었습니다.
Child.js
import { forwardRef } from 'react';
const Child = forwardRef((_,ref) => {
return <input type="text" ref={ref} />;
});
export default Child;