useStateWithHistory 훅이란?
리액트에서 흔하게 쓰이는 useState를 사용하면서 history를 기록하여 필요하다면 과거의 상태값을 가져다 쓸 수 있게 해주는 커스텀 훅이다
코드 살펴보기
function useStateWithHistory(initialState) {
const [state,setStateInternal] = useState(initialState);
const history = useRef([state]);
const historyIndex = useRef(0);
// state를 셋하면
// history에 상태값을 넣고
// historyIndex를 +1 해준다
// 그리고 마지막엔 현재 상태값에 새로운 state를 set해준다.
const setState = newState => {
history.current.push(newState);
historyIndex.current = history.current.length - 1;
setStateInternal(newState);
}
// historyIndex가 0이면 history가 비어있다는 것이므로 return 시켜버린다
// 만약 history가 남아있다면 인덱스를 마이너스 1 해준다;
// push 했던 history에서 해당 인덱스에 있던 상태값을 새로운 상태값으로 갱신한다
const goBack = () => {
if(historyIndex.current === 0) return;
historyIndex.current--;
setStateInternal(history.current[historyIndex.current]);
}
// goBack과 비슷한 원리로 작성한다
// goBack은 과거 히스토리로 돌아가는 반면 goForward는 다시 앞으로 돌아갈때 사용한다.
const goForward = () => {
if(historyIndex.current >= history.current.length - 1) return;
historyIndex.current +=1;
setStateInternal(history.current[historyIndex.current]);
}
return [state,setState,goBack,goForward,history.current];
}
결론
리액트에서 상태관리를 하다보면 지속적으로 히스토리를 남겨 유용하게 쓰이는 상황이 존재하기 마련이다.
만약 과거의 상태값들을 사용해야할때 새롭게 값을 연산하는게 아니라, 캐싱되어있던 과거 값들을 그대로 이용하면 훨씬 더 좋은 퍼포먼스를 가진 프론트 웹을 만들 수 있지 않을까 생각된다.