Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/timurkr/zimmer-context
Complex zustand slices patterns made simple with full typescript support
https://github.com/timurkr/zimmer-context
context immer npm npm-package react zustand
Last synced: 3 months ago
JSON representation
Complex zustand slices patterns made simple with full typescript support
- Host: GitHub
- URL: https://github.com/timurkr/zimmer-context
- Owner: TimurKr
- License: mit
- Created: 2024-02-10T11:49:16.000Z (12 months ago)
- Default Branch: main
- Last Pushed: 2024-02-18T17:40:57.000Z (12 months ago)
- Last Synced: 2024-10-08T15:05:59.111Z (4 months ago)
- Topics: context, immer, npm, npm-package, react, zustand
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/zimmer-context
- Size: 724 KB
- Stars: 4
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# Complex zustand slices patterns made simple with full typescript support
## Getting Started
Install the package with
```bash
npm install zimmer-context
```## Using the package
It is dead simple, this library provides only 2 functions:
- `createStoreSlice` to define your slices
- `createGlobalStoreContext` to use your slices and get your `ContextProvider` and `useStoreContext` hook to use the storeI felt there was too much boilerplate when using zustand with immer and persist, especially as my projects grew, so I created this package. Everything is fully typed and as simple as possible.
### 1. Creating slices
Create a file `store/fishSlice.ts`, where you define your slice with `createStoreSlice`. First define your state and actions. then inside the createStoreSlice define the default values and the functions. you have access to set and get fucnctions to retrieve and manipulate with the data in this slice. You cannot access data in another slices, as at the time of defining your slice, typescript doesn't know aobut the structure of other slices.
```typescript
import { createStoreSlice } from "zimmer-context";type FishState = {
count: number;
};type FishActions = {
increment: (qty: number) => void;
decrement: (qty: number) => void;
};export const fishSlice = createStoreSlice(
(set, get) => ({
count: 0,
increment: (qty: number) => set((state) => ({ count: state.count + qty })),
decrement: (qty: number) => set((state) => ({ count: state.count - qty })),
})
);
```and another `store/bearSlice.ts` slice like so:
```typescript
import { createStoreSlice } from "zimmer-context";type BearState = {
count: number;
};type BearActions = {
increment: (qty: number) => void;
decrement: (qty: number) => void;
};export const bearSlice = createStoreSlice(
(set, get) => ({
count: 0,
increment: (qty: number) => set((state) => ({ count: state.count + qty })),
decrement: (qty: number) => set((state) => ({ count: state.count - qty })),
})
);
```### 2. Create your global store using slices
In another file (say `store/global_store.ts`) import all of the slices and create the global store:
```typescript
"use client";import { createGlobalStoreContext } from "zimmer-context";
import { bearSlice } from "./bear_slice";
import { fishSlice } from "./fish_slice";export const { ContextProvider, useStoreContext } = createGlobalStoreContext(
{
fish: fishSlice,
bear: bearSlice,
},
{
persist: {
// Do not specify to not use persist
version: 1, // Persist version, change whenever there is a breaking change in the structure of the store
},
}
);
```### 3. Provide the context with `ContextProvider`
Here you can override the initial store state with your data, such as fetched one, or from URL search parameters.
```typescript
import { ContextProvider } from "store/global_store";export default async function ReactComponent({
children,
}: {
children: React.ReactNode;
}) {
return (
{children}
);
}
```### 4. Use the store with `useStoreContext`
Inside the ContextProvider you can get the state like so:
```typescript
import { useStoreContext } from "store/global_store";export default async function DisplayCounts() {
const { fish, bear } = useStoreContext((state) => state);
return (
fish: {fish.count}
bear: {bear.count}
{
fish.decrement(1);
}}
>
Bear eats fish
);
}
```### Contributing
Feel free to open issues and contribute by creating pull requests! I am open to any and all suggestions.