Store
The API was created to satisfy the need of an external state store which does not reside within the application tree, and allows for precision updates when state changes.
Creating a Store
To create a store, you need to provide two arguments to the function:
- Initial State: The initial state of your store.
- : This is a
function that receives two arguments -
setState
andgetState
- and returns an object containing methods for interacting with the store state. These methods will be accessible through the returned store object.
import { createStore } from "kaioken"
const useCountStore = createStore(0, (set, get) => ({
increment: () => set((state) => state + 1),
decrement: () => set((state) => state - 1),
add: (value) => set(() => get() + value),
}))
Accessing Store State and Methods
There are two main ways to interact with the store:
useStore
hook: A Store object is callable within a component and returns the current store value and methods.
function Counter() { const { value, increment, decrement } = useCountStore() return ( <div> <p>Count: {value}</p> <button onclick={increment}>Increment</button> <button onclick={decrement}>Decrement</button> </div> ) }
You can provide a function to
useStore
to return a computed value. This will cause the component to only update when the result of that computation changes:function TodoItem({ id }) { const { value: todo, toggle } = useTodoStore((state) => { return state.find((item) => item.id === id) }) // ... }
You can also provide a second function, allowing you to specify how the result of your computation should be compared:
function TodoList() { const { value: items } = useTodoStore(null, (prev, next) => { return prev.length === next.length }) return ( <ul> {items.map((item) => ( <TodoItem key={item.id} id={item.id} /> ))} </ul> ) }
In the above example, the TodoList component will only update when the number of items in the store changes. We can also provide
null
as the first argument, which means the comparison will use the current state.
Direct Access: You can also access the store's methods and state directly using the returned object from createStore:
useCountStore.getState() // Returns the current state useCountStore.setState((state) => state + 1) // Updates the state useCountStore.methods.increment() // Calls the method defined in the method factory /** * Subscribe to the store, providing a function to run whenever state changes. * Subscribing in this way returns a function to unsubscribe. */ const unsub = useCountStore.subscribe((newValue) => console.log(newValue))