티스토리 뷰
서론
useRef는 기본적으로 요소에 접근할 때 사용한다고 알고 있었다.
하지만 렌더링 부분과 상관없는 값을 다룰 때도 사용할 수 있다!
useState의 상태는 변화할 때마다 리렌더링이 이루어지지만, useRef의 값은 변화할 때마다 리렌더링이 이루어지지 않는다.
현재까지 useState로 모든 값을 관리했다. 그래서 렌더링 부분과 상관없는 값이 변화할 때도 리렌더링이 이루어졌다.
본론
아래는 현재 프로젝트의 수정 전 코드이다. (다른 부분은 코드를 생략했다)
디바운싱을 구현한 코드인데, 이 때 timer의 값을 useState로 관리했다.
아래 코드의 과정은 검색창(input)에서 타자를 칠 때마다 onChange이벤트에 의해 onDebounce함수가 실행되고 -> setTimeout에 의해 0.6초 후에 해당 로직을 실행하라고 예약한다. -> 이 때 0.6초 안에 또 검색창 onChange이벤트가 발생하면 이전에 예약해논 setTimeout을 취소하고, 새로 setTimeout에 의해 0.6초 후에 실행하라는 예약을 걸어둔다.
(디바운싱 - 처음 또는 마지막만 실행되게 하는 것, 검색창에서 타자를 치다가 특정 시간 멈출 때, enter를 안해도 자동적으로 검색을 해줄 수 있다)
그런데 이 때 매번 타자를 칠 때 마다 onDebounce함수가 실행되고 -> setTimeout의 이전 예약은 취소하고, 새로 예약을 한다. (이 뜻은 매번 newTimer, timer의 값이 바뀐다는 뜻이다) -> timer를 useState로 관리했기 때문에 timer의 값이 바뀔 때마다 매번 리렌더링이 이루어진다 -> 리렌더링이 이루어져도 렌더링 부분에서 달라질 게 없다! -> 그럼 useRef로 timer의 값을 관리해도 되는 것이다!
const SearchInput = ({ }) => {
const [timer, setTimer] = useState(0);
const onDebounce = useCallback(async (e) => {
if (timer) {
clearTimeout(timer);
}
const newTimer = setTimeout(async () => {
//여기 실행
}, 600);
setTimer(newTimer);
},[]);
return (
<>
<>
<Input
placeholder="고양이를 검색해보세요."
onChange={onDebounce}
value={input}
autoFocus
/>
</>
</>
);
};
export default SearchInput;
따라서 렌더링 부분과 상관없는 값을 관리할 때 useRef를 사용하여 다음과 같이 코드를 수정했다.
이제 timer의 값이 바뀔 때마다 리렌더링이 이루어지지 않는다!
const SearchInput = ({ }) => {
const timer = useRef(0);
const onDebounce = useCallback(async (e) => {
if (timer.current) {
clearTimeout(timer.current);
}
timer.current = setTimeout(async () => {
//여기 실행
}, 600);
},[]);
'프론트엔드' 카테고리의 다른 글
CSS 로더 설정하기 (0) | 2022.08.11 |
---|---|
웹팩의 빠른 로딩 속도 비교하기 (0) | 2022.08.11 |
PR에서 테스팅 후 성공시에만 자동 Merge하기 (0) | 2022.08.03 |
useState 비동기 작동, 불변 메서드 문제 해결 과정 (0) | 2022.08.01 |
www.naver.com을 입력했을 때 일어나는 일 (0) | 2022.06.15 |
- Total
- Today
- Yesterday