일반적으로 우리가 상태값을 관리할 때는 useState를 사용한다.
거기에서 state 값이 변경되면 리렌더링이 발생하면서 화면이 새롭게 그려진다.
그런데, 상태값이 변경되더라도 굳이 리렌더링이 필요없는 경우에도 useState를 사용하면
상태가 변경되므로 리렌더링이 발생한다.
const Component = () => {
const [state, setState] = useState("");
return (
<input value={state} onChange={e => setState(e.currentTaget.value)}/>
)
}
input에 값을 입력하면 입력할 때마다 리렌더링이 발생한다.
하지만 입력된 값이 변경될 때마다 굳이 화면을 리렌더링해야할 상황인가? 생각해보면 아니다.
만약에 입력한 값이 어디서 동시에 보여져야 한다면 리렌더링이 발생해서 입력한 값이
다른 곳에서 표시되야하므로 useState를 사용하는 방식이 필요할 수 있다.
하지만 회원가입과 같은 일반적으로 input을 사용하는 경우에는 굳이 리렌더링이 필요없다.
이때 사용할 수 있는 것이 useRef이다.
const Component = () => {
const inputRef = useRef();
const handleInputCheck = () => {
console.log(input.current.value);
}
return (
<form>
<input ref={inputRef} />
<button onClick={handleInputCheck}>확인</button>
</form>
)
}
다음과 같이 ref를 사용해서 실제로 쓰이는 곳에서 value를 가지고 와 사용할 수 있다.
useRef의 current는 리렌더링이 발생해도 상태값이 변경되지 않는 특징이 있고,
마찬가지로 current가 변경되더라도 리렌더링을 발생시키지 않는 특징이 있다.
그래서 꼭 Dom을 컨트롤하기 위해서 useRef를 사용하는 것이 아닌,
리렌더링이 발생해도 변하지 않는 상태를 유지하기 위해서도 사용할 수 있다.
const Component = () => {
const audioRef = useRef(new Audio());
const [isPlaying, setIsPlaying] = useState(false);
const handleAudioToggle = () => {
setIsPlaying(prev => !prev);
isPlaying ? audioRef.current.pause() : audioRef.current.play();
}
return (
<div>
<button onClick={handleAudioToggle}>버튼</button>
</div>
)
}
audio를 변수로 만드는 것이 아닌 useRef에서 new Audio를 선언해서 사용했다.
그 이유는 버튼의 클릭 이벤트가 발생할 때마다 audioRef는 변경되지 않고 유지된다.
만약 일반 변수로 new Audio를 선언하면 state값이 변하면서 새로운 Audio가 계속 생성되면서
원하는 기능이 불가능해진다.
이번에 이렇게 정리한 이유는 useRef가 만능이다! 를 말하려는 것이 아닌
상황에 따라서 useState, useRef를 나눠서 쓴다면 최적화에 도움이 될 것이다!
'React > 기능' 카테고리의 다른 글
[React] 성능 측정하기 (0) | 2022.10.28 |
---|---|
[React] useCallback 그리고 React.memo (0) | 2022.10.27 |
[React] Map을 State로 사용하기 (0) | 2022.10.25 |
[React] 컴포넌트 합성 (1) | 2022.10.21 |
[React] react-router-dom 사용하기 (1) | 2022.10.05 |