코딩쌀롱

[React] Lazy initial state 본문

개발공부

[React] Lazy initial state

이브✱ 2021. 4. 30. 03:15

 

useState의 지연 초기화를 통해 리액트 함수 컴포넌트를 최적화시킬 수 있다.

 

// 예제 1

const Counter = () => {
  const [count, setCount] = useState(
    Number.parseInt(window.localStorage.getItem(cacheKey)),
  )

  useEffect(() => {
    window.localStorage.setItem(cacheKey, count)
  }, [cacheKey, count])

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount((prevCount) => prevCount - 1)}>-</button>
      <button onClick={() => setCount((prevCount) => prevCount + 1)}>+</button>
    </div>
  )
}

 

// 예제 2

const Counter = () => {
  const [count, setCount] = useState(() =>
    Number.parseInt(window.localStorage.getItem(cacheKey)),
  )

  useEffect(() => {
    window.localStorage.setItem(cacheKey, count)
  }, [cacheKey, count])

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount((prevCount) => prevCount - 1)}>-</button>
      <button onClick={() => setCount((prevCount) => prevCount + 1)}>+</button>
    </div>
  )
}

 

예제1, 2의 useState 인자 값에 차이가 있다.

 

직접적인 값 대신 함수를 useState의 인자로 넘기는 것을 지연 초기화(lazy initial state)라고 한다.

 

useState 훅은

1. Counter 컴포넌트를 처음 렌더링할 때 count 를 초기 값으로 생성한다.

2. setCount를 호출하면 Counter 함수가 다시 호출되고 count 는 갱신된다.

3. 상태값이 변하니까 리렌더링되고, 리렌더링하는 동안 localStorage에서 값을 찾음. 굳이!! 또!!

 

초기값 설정이니까 최초 렌더링시에만 필요한데 상태값이 바껴서 리렌더링이 되면 그 때마다 계속 불필요한 계산을 하는 것. 이를 방지하기 위해 지연 초기화를 한다.

 

더 쉽게 이해하기 위해 직접적인 값일 때(예제1) 변수에 담아보았다.

// 예제 1
const Counter = () => {
  const initialValue = Number.parseInt(window.localStorage.getItem(cacheKey))
  const [count, setCount] = useState(initialValue)
  // ...
  
// 예제 2
const Counter = () => {
  const [count, setCount] = useState(function() {
    return Number.parseInt(window.localStorage.getItem(cacheKey)),
  })
  // ...

예제1에서는 Counter 함수가 호출되어 리렌더링이 발생할 때마다 localStorage에서 값을 가져온다. 예제2에서는 리렌더링될 때마다 useState에 함수를 넘기지만 실행은 최초 렌더링 시에만 되기 때문에 리렌더링 시 불필요한 계산을 하지 않는다.

 

지연 초기화는 '비용이 큰 계산'일 때 사용하자. 항상 지연 초기화를 사용하는 것이 좋은 것은 아니다. 단순 원시값이나 이미 계산된 값은 계산이 필요하지 않기 때문에 값만 전달하는 것이 좋다. 이런 경우에도 지연 초기화를 한다면 지나친 최적화다!

 

 


참고📚

TOAST UI - 글자 4개로 리액트 컴포넌트를 최적화하는 방법

 

 

 

Comments