[Zustand] 상태 업데이트

이영우·2023년 5월 29일
0

Zustand

목록 보기
2/3
post-thumbnail

📌 Zustand를 사용하여 상태를 업데이트 하는 방법에 대해 정리해보았다. 기본적인 Flat Update (단일 수준의 상태 업데이트), 그리고 Deeply nested object (중첩 객체)를 업데이트 하는 방법에 대한 내용이다.


Flat Update

Flat Update란?
Flat Update는 객체의 얕은 수준에서 진행되며, 기존 상태 객체와 새로운 상태 객체를 얕은 병합을(shallow merge)하여 업데이트하는 방식이다. 객체의 중첩(nested)된 속성까지는 업데이트되지 않는다.

Zustand에서 제공되는 set 함수를 호출하여 상태를 업데이트하면, 스토어의 기존 상태와 얕게 병합된다.

아래는 Zustand에서 Flat Update를 통해 상태를 업데이트하는 예제이다.

export const userInfoStore = create<UserStore>((set) => ({
  // {...}
  // Flat update
  updateUser: (newUser) =>
    set((state) => ({ user: { ...state.user, ...newUser } })),
}));

+추가: set 함수의 객체를 병합시키는 동작을 두번째 인자로 비활성화 할 수 있다.

set((state) => newState, true)  // replace

중첩된 객체 업데이트

Flat Update는 중첩된 객체의 상태 값 업데이트를 직접적으로 지원하지 않으며, 주로 최상위 레벨 속성에 대한 업데이트에 사용된다.

그렇다면, 중첩된 객체에 대한 상태 값을 업데이트 하려면 어떻게 해야할까?
깊은 수준 업데이트를 사용하여 내부 상태를 직접 업데이트 하지 않고, 새로운 객체로 대체하는 방식으로 처리해야한다.

아래 예제를 보자.


export const userInfoStore = create<UserStore>((set) => ({
  // 업데이트 할 상태 값
  user: {
    name: '해린',
    age: 17,
    preferences: {
      theme: 'dark',
      language: 'kor',
    },
  },
  
  // Deep update
  updatePreferences: (newPreferences) =>
    set((state) => ({
      user: {
        ...state.user,
        preferences: {
          ...state.user.preferences,
          ...newPreferences,
        },
      },
    })),
}));

일반적인 방식은, 상태 객체의 각 수준을 복사하여 병합하는 것이다.
나의 예제에서는 객체가 한번밖에 중첩되어있지 않아 그리 복잡해보이지 않을 수 있다.

하지만 depth가 3~4개가 되는 순간부터 코드가 매우 길어지고, 불변성 유지에 문제가 생길 수 있다.

Zustand 공식 문서에는 이를 해결할 수 있는 다른 해결 방법도 몇가지 작성되어있지만, 이 글에서는 immer를 활용하여, 이러한 문제를 쉽게 해결했다.

export const userInfoStore = create<UserStore>((set) => ({
  user: {
    name: '해린',
    age: 17,
    preferences: {
      theme: 'dark',
      language: 'kor',
    },
  },
  
  // Deep update with immer
  updatePreferences: (newPreferences) =>
    set(
      produce((state) => {
        state.user.preferences = {
          ...state.user.preferences,
          ...newPreferences,
        };
      })
    ),
}));

immer 라이브러리의 produce 함수를 활용하면, 코드가 간결해지고, 성능을 최적화하며 깊은 수준 복사를 보다 쉽고 안전하게 처리할 수 있다.


결과


마치며

이렇게 Zustand에서 상태를 업데이트하는 방법에 대해서 정리를 해보았다.
사실 오늘 내용은 예제보다 이론에 대한 것이 더 많고, 중요했던 것 같다.
아주 천천히지만, 꾸준히 학습을 하며 성장하는 것은 재밌다!
조금 힘들어도 더 바쁘게 살아봐야지. 👍


참고 문서

profile
학습한 기술 지식들을 기록합니다.

0개의 댓글