In examples, we dont know how to use immer outside of the store
implementation.
Here's how to.
// store.ts
import { immer } from 'zustand/middleware/immer'
import { CreateOneShopOrderFromCheckoutInput } from '@/graphql/generated'
import { WritableDraft } from 'immer/dist/internal'
type State = {
bears: number
} & CreateOneShopOrderFromCheckoutInput
interface Actions {
increaseBear: (by: number) => void
clearCheckout: () => void
setState: (updater: (state: WritableDraft<State>) => void) => void
}
// ...
export const useCheckout = create<State & Actions>()(
devtools(
immer(
persist((set) => ({
...initialState,
increaseBear: (by) => set((state) => ({ bears: state.bears + by }), undefined, 'increase'),
clearCheckout: () => set({ ...initialState }),
setState: (e) => set(e) // immer exported
}), {
name: "checkout",
})
)
)
)
// src/pages/checkout/form/shipping/city.tsx
const City: React.FC = () => {
const { setValue, value } = useCheckout(
(state) => ({
setState: state.setState,
value: state.Shipping.city,
}),
shallow
);
console.log("RENDERING CITY");
return (
<div>
<Input
label={"City"}
value={value}
onChange={(e) => {
setState((state) => {
// Using immer function inside component
state.Shipping.city = e.target.value;
});
}}
/>
</div>
);
};
export default City;