zustand slice namespace /demo

标签:zustand, typescript, dx
分类:摘抄本
概述:/
创建:
Published On
useStore.ts
import {create} from 'zustand';
import {immer} from 'zustand/middleware/immer';

import {createBarState} from './wallet/barState';
import {createFooState} from './modal/fooState';
import type {CombinedState, Set} from './types';

export const useStore = create<CombinedState>()(
  persist(
    immer((...api) => ({
      bar: createBarState(...api),
      foo: createFooState(...api),
    })),
    {
      name: 'my-store-name',
      partialize: (state) => ({
        // Include the keys you want to persist in here.
        bar: {
          baz: state.bar.baz,
        },
      }),
      merge: (persistedState, currentState) => {
        // persistedState is unknown, so we need to cast it to CombinedState | undefined
        const typedPersistedState = persistedState as CombinedState | undefined;

        return {
          bar: {
            // We need to do a deep merge here because the default merge strategy is a
            // shallow merge. Without doing this, our actions would not be included in
            // our merged state, resulting in unexpected behavior.
            ...currentState.bar,
            ...(typedPersistedState?.bar || {}),
          },
          foo: currentState.foo,
        };
      },
    },
  ),
);

barState.ts
import type {BarStateDefinition, BarStateType, StateSlice} from '../types';

const initialBarState: BarStateDefinition = {
  baz: '',
  qux: '',
};

export const createBarState: StateSlice<BarStateType> = (set) => ({
  ...initialBarState,
  setBaz: (value) =>
    set((state) => {
      state.bar.baz = value;
    }),
  setQux: (value) =>
    set((state) => {
      state.bar.qux = value;
    }),
});

fooState.ts
import type {FooStateDefinition, FooStateType, StateSlice} from '../types';

const initialFooState: FooStateDefinition = {
  thud: '',
  waldo: '',
};

export const createFooState: StateSlice<FooStateType> = (set) => ({
  ...initialFooState,
  setThud: (value) =>
    set((state) => {
      state.foo.thud = value;
    }),
  setWaldo: (value) =>
    set((state) => {
      state.foo.waldo = value;
    }),
});

types.ts
import {StateCreator} from 'zustand';

export interface BarStateDefintion {
  baz: string;
  qux: string;
}

export interface BarStateActions {
  setBaz: (value: string) => void;
  setQux: (value: string) => void;
}

export interface FooStateDefintion {
  thud: string;
  waldo: string;
}

export interface FooStateActions {
  setThud: (value: string) => void;
  setWaldo: (value: string) => void;
}

export type BarStateType = BarStateActions & BarStateDefintion;
export type FooStateType = FooStateActions & FooStateDefintion;

export interface CombinedState {
  bar: BarStateType;
  foo: FooStateType;
}

export type StateSlice<T> = StateCreator<
  CombinedState,
  [['zustand/immer', never]],
  [['zustand/persist', Partial<T>]],
  T
>;

zustand slice namespace /demo

https://infen.cc/snippets/03_zustand-slice-namespace[Copy]