Helping to make zustand stores easier
pnpm install simple-scoped-zustand
import { createScopedStore } from 'simple-scoped-zustand';
export const useCatStore = create(
combine(
{
cats: [
{
id: 1,
color: 'black',
name: 'Felix',
},
{
id: 2,
color: 'orange',
name: 'Garfield',
},
{
id: 3,
color: 'white',
name: 'Snowball',
},
] as Cat[],
selectedCatId: null as number | null,
},
set => ({
selectCat: (id: number) => {
set({ selectedCatId: id });
},
})
)
);
export const [CurrentCatProvider, useCurrentCat] = createScopedStore(
useCatStore,
store =>
({ id }: { id: number }) => {
const cat = store.cats.find(cat => cat.id === id);
if (!cat) throw new Error(`No cat found with id ${id}`);
return cat;
}
);
export function MyComponent() {
const [id, setId] = useState(1);
return (
<>
<button onClick={() => setId(1)}>Set cat id to 1</button>
<button onClick={() => setId(2)}>Set cat id to 2</button>
<button onClick={() => setId(3)}>Set cat id to 3</button>
<button onClick={() => setId(4)}>Set cat id to 4</button>
<CurrentCatProvider id={id}>
<CatScreen />
</CurrentCatProvider>
</>
);
}
function CatScreen() {
const cat = useCurrentCat();
const color = useCurrentCat(cat => cat.color);
return (
<div>
name: {cat.name}, color: {color}
</div>
);
}
Creates a scoped store and provides a React context for it. This allows for creating a subset ("scope") of a larger store that can be provided and consumed using React Context.
-
initialStore (
UseScopedStore<StoreState>
): The initial Zustand store or a custom hook that behaves like a store. This store is used as the basis for creating the scoped store. -
scope (
(store: StoreState) => (args: ScopeArgs) => ScopeValue
): A function that takes the store state and returns another function. This returned function takesScopeArgs
and returns aScopeValue
, defining the scope of the store.
An array containing two elements:
-
StoreProvider (
React.FC<StoreProviderProps>
): A React context provider component that provides the scoped store value to its children. It accepts all scope arguments as props in addition tochildren
. -
useStore (
function
): A hook that allows consuming the scoped store value. It can be called with a selector function to select a part of the scoped store value.
-
UseScopedStore<S>
: A union type that either represents a Zustand store or a function that directly returns the store state or a selected part of it. -
ScopeArgs
: The type of arguments passed to thescope
function to define or modify the scope of the store. -
ScopeValue
: The type of value returned by thescope
function, representing the scoped part of the store.
const [StoreProvider, useStore] = createScopedStore(initialStore, scope);
// Inside a component
return (
<StoreProvider {...scopeArgs}>
{/* Children that can use useStore hook */}
</StoreProvider>
);
- children (
React.ReactNode
): The children that will have access to the scoped store. - ...scopeArgs (
ScopeArgs
): Arguments required by thescope
function to define the scoped store value.
When called without arguments, it returns the entire scoped store value.
const scopedValue = useStore();
- selector (
(state: ScopeValue) => U
): A function that selects a part of the scoped store value.
Returns the result of the selector function applied to the scoped store value.
const selectedValue = useStore(state => state.partOfScopedValue);
© veloii 2024