Skip to content

createStore

Function that creates a store.

You can think of a store as your app state. You can define multiple keys/values, each key will create separated subscription (more explained here). If you want to persist the value - you can simply wrap it in Synchronizer

It can be imported from stan-js or from stan-js/vanilla you can read more about usage with vanilla-js here

import { createStore } from 'stan-js'
export const { actions, getState, reset, effect, useStore, useStoreEffect } = createStore({
count: 0,
name: 'John',
notifications: [] as Array<Notification>
})

createStore returns such things:

actions

Object that contains all functions that allows for updating the store’s state

Action name is generated automatically based on given key to the store count -> setCount

You can pass the next state directly, or a function that calculates it from the previous state - similarly to the useState hook

getState

Function that returns current state of the store

const { count } = getState()
console.log(count)

reset

Function that resets store state to the initial values

You can either pass all the keys that you want to be reset, or if you won’t pass any key WHOLE store will be reset.

reset('count')
// Only count value will be reset
reset('name', 'notifications')
// name and notifications will be reset
reset()
// Whole store will be reset

effect

Function that allows to subscribe to store’s values change and react to them

It takes callback with current store’s state that will be triggered on every store’s value that you are using

const dispose = effect(({ count }) => {
console.log(count)
})

useStore

React’s hook that allows to access store’s values and to update them

const { count, setCount, setName } = useStore()
console.log(count)
setCount(prev => prev + 1) // Component will re-render
setName('Anna') // Component won't re-render because it doesn't subscribe to name

useStoreEffect

React’s hook that uses effect under the hood

You should use it inside React components, and in the other places feel free to use effect

useStoreEffect(({ count }) => {
console.log(count)
})

If you want to react to changes in the store and a component’s state, you can pass a second argument - an array of dependencies

const [componentState, setComponentState] = useState(0)
useStoreEffect(({ count }) => {
console.log(count + componentState)
}, [componentState])

Computed (derived) state

You can create computed value based on another value in store by using getter:

export const { useStore } = createStore({
counter: 0,
get doubleCounter() {
return this.counter * 2
},
get counters() {
return `${this.counter} is two times smaller than ${this.doubleCounter}`
}
})

Now, whenever value of count changes doubleCounter will be recalculated. You can even create derived state from derived state!

batchUpdates

Function that allows to batch updates to the store’s state

const { batchUpdates, effect, actions } = createStore({
firstName: 'John',
lastName: 'Doe',
})
effect(({ firstName, lastName }) => {
console.log(`${firstName} ${lastName}`)
})
actions.setFirstName('Jane')
// console.log: Jane Doe
actions.setLastName('Bar')
// console.log: Jane Bar
batchUpdates(() => {
actions.setFirstName('Mark')
actions.setLastName('Smith')
// console.log: Mark Smith
})

useHydrateState

Function that allows to hydrate store’s state with the initial values

const { useHydrateState } = createStore({
count: 0,
name: 'John',
notifications: [] as Array<Notification>
})
useHydrateState({
count: 10,
name: 'Jane',
notifications: [{ message: 'Hello' }]
})
// Now the store's state is:
// count: 10, name: 'Jane', notifications: [{ message: 'Hello' }]