useState의 지연 초기화 (Lazy initial state)
공식문서에서 다루는 Lazy initial state은 다음과 같이 설명이 되어 있다.
The initialState argument is the state used during the initial render. In subsequent renders, it is disregarded. If the initial state is the result of an expensive computation, you may provide a function instead, which will be executed only on the initial render:
const [state, setState] = useState(() => {
const initialState = someExpensiveComputation(props);
return initialState;
});
대강 번역하자면 useState의 초기값은 처음 렌더될 때만 사용되며 그 이후에는 disregarded 즉, 무시된다. 따라서 해당 초기값을 얻는데 많은 리소스를 사용해야 된다면, 직접 useState(initialValue)로 적는 것보다 함수 형태로 적어서 초기 렌더에만 사용하도록 만들 수 있다는 것이다.
아래 두 코드를 보자. useState를 활용하여 localstorage에 있는 값을 숫자형으로 변환한 값을 count라는 state에 넣는 작업이다. 이 작업을 지연 초기화하기 위해서 함수형으로 쓴 것이 하단의 코드다.
// 일반적인 useState 사용법
const [count, setCount] = useState(
Number.parseInt(window.localStorage.getItem(cacheKey)),
)
// Lazy initial state, which is better!
const [count, setCount] = useState(() =>
Number.parseInt(window.localStorage.getItem(cacheKey)),
)
그런데 언제 지연 초기화를 사용해야 할까? 문서에서는 해당 값을 찾는데 비용이 높으면 사용하라고 했다. 값을 얻기 위해 어떤 함수를 호출하거나, 계산을 해야 하는 경우에는 비용이 높은 것으로 간주하면 된다.
예를 들어 new Date를 통해 현재 날짜, 시간을 가져오는 작업과 같은 경우 비용이 높은 것으로 봐야 한다.
// 비용 큼
const [time, setTime] = useState(() => new Date())