Как осуществить частичное сохранение состояния с использованием библиотеки Zustand?

Привет всем! <br/> У меня возникла задача: нужно частично сохранить состояние в локальном хранилище (localStorage). Я использую React 19 вместе с Zustand 5. <br/> Вот пример кода для состояния: <br/> <pre><code class="javascript">import { create } from "zustand";
import { persist } from "zustand/middleware";

interface AuthState {
  isAuth: boolean | null;
  login: string;
  token: string | null;
  context: string | null;
  checkAuth: () =&gt; Promise&lt;void&gt;;
  extractLoginFromContext: () =&gt; void;
  setAuth: (isAuth: boolean, token: string, context: string) =&gt; void;
}

// Создаем Zustand Store
export const useAuthStore = create&lt;AuthState&gt;()(
  persist(
    (set, get) =&gt; ({
      isAuth: null,
      login: "",
      token: null,
      context: null,

      checkAuth: async () =&gt; {
        const { token, context } = get();
        if (!token) {
          set({ isAuth: false });
          return;
        }

        try {
          const response = await fetch("https://example.com/api/validate-token", {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
              Authorization: `Bearer ${token}`,
            },
          });

          if (response.ok) {
            set({ isAuth: true });
            get().extractLoginFromContext();
          } else {
            set({ isAuth: false, token: null, context: null });
          }
        } catch (error) {
          console.error("Ошибка проверки авторизации:", error);
          set({ isAuth: false });
        }
      },

      extractLoginFromContext: () =&gt; {
        const { context } = get();
        if (!context) return;

        try {
          const decodedContext = JSON.parse(atob(context));
          set({ 
  • 28 января 2025 г. 6:54
Ответы на вопрос 1
Вы можете использовать Zustand для частичного сохранения состояния в `localStorage`, добавив соответствующую настройку в ваш store. Чтобы сохранить только некоторые части состояния, вы можете использовать функцию `select`, которая позволяет выбирать конкретные поля для сохранения.

Вот пример кода, в котором используется Zustand для частичного сохранения состояния:

```javascript
import { create } from "zustand";
import { persist } from "zustand/middleware";

interface AuthState {
  isAuth: boolean | null;
  login: string;
  token: string | null;
  context: string | null;
  checkAuth: () => Promise<void>;
  extractLoginFromContext: () => void;
  setAuth: (isAuth: boolean, token: string, context: string) => void;
}

// Создаем Zustand Store
export const useAuthStore = create<AuthState>()(
  persist(
    (set, get) => ({
      isAuth: null,
      login: "",
      token: null,
      context: null,

      checkAuth: async () => {
        const { token, context } = get();
        if (!token) {
          set({ isAuth: false });
          return;
        }

        try {
          const response = await fetch("https://example.com/api/validate-token", {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
              Authorization: `Bearer ${token}`,
            },
          });

          if (response.ok) {
            set({ isAuth: true });
            get().extractLoginFromContext();
          } else {
            set({ isAuth: false, token: null, context: null });
          }
        } catch (error) {
          console.error("Ошибка проверки авторизации:", error);
          set({ isAuth: false });
        }
      },

      extractLoginFromContext: () => {
        const { context } = get();
        if (!context) return;

        try {
          const decodedContext = JSON.parse(atob(context));
          set({ login: decodedContext.login });
        } catch (error) {
          console.error("Ошибка декодирования контекста:", error);
        }
      },

      setAuth: (isAuth, token, context) => {
        set({ isAuth, token, context });
      },
    }),
    {
      name: "auth-storage", // имя для localStorage
      partialize: (state) => ({ isAuth: state.isAuth, token: state.token }), // сохраняем только эти поля
    }
  )
);
```

### Объяснения:

1. **partialize**: Параметр `partialize` определяет, какие части состояния необходимо сохранить. В приведенном примере мы сохраняем только `isAuth` и `token`. Поля `login` и `context` не будут сохранены в `localStorage`.

2. **persist**: Вы обернули свой основный `zustand` store в middleware `persist`, чтобы использовать возможности сохранения состояния.

3. **функции для изменения состояния**: Вы определили различные функции для управления состоянием, такие как `checkAuth`, `extractLoginFromContext` и `setAuth`.

Таким образом, вы можете контролировать, какие части состояния сохраняются в `localStorage`, что может быть полезно для уменьшения объема данных, сохраняемых пользователем, или для управления конфиденциальностью.
Похожие вопросы