createStore
Method for creating a store
createStore<T>(defaultState: T): Store<T>
createStore<T, SerializedState extends Json = Json>(defaultState: T, config: {
name?: string
updateFilter?: (update: T, current: T) => boolean
serialize?: 'ignore' | {
write: (state: State) => SerializedState
read: (json: SerializedState) => State
}
}): Store<T>
Arguments
defaultState(State): Default stateconfig(Object): Optional configurationname(String): Name for the store. Babel plugin can set it from the variable name, if not passed explicitly in config.updateFilter(Function): Function that prevents store from updating when it returnsfalse. Accepts updated state as the first argument and current state as the second argument. Redundant for most cases since store already ensures that update is notundefinedand not equal (!==) to current state (sinceeffector 21.8.0)serialize: 'ignore': Option to disable store serialization when serialize is called (sinceeffector 22.0.0)serialize(Object): Configuration object to handle store state serialization in custom way.write- called on serialize, transforms value to JSON value - primitive type or plain object/array.read- parse store state from JSON value, called on fork, if providedvaluesis result ofserializecall.
Returns
Store: New store
Example
import {createEvent, createStore} from 'effector'
const addTodo = createEvent()
const clearTodoList = createEvent()
const $todos = createStore([])
// Will update store when addTodo is fired
.on(addTodo, (list, todo) => [...list, todo])
// Will reset store to default state when clearTodos is fired
.reset(clearTodoList)
// Create mapped store
const $selectedTodos = $todos.map(todos => {
return todos.filter(todo => todo.selected)
})
// Log initial store value and each change
$todos.watch(todos => {
console.log('todos', todos)
})
// => todos []
addTodo('go shopping')
// => todos ['go shopping']
addTodo('go to the gym')
// => todos ['go shopping', 'go to the gym']
clearTodoList()
// => todos []
Example with updateFilter
import {createEvent, createStore, forward} from 'effector'
const punch = createEvent()
const veryStrongHit = createEvent()
const $lastPunchStrength = createStore(0, {
// If store should be updated with strength less than 400 kg
// update will be skipped
updateFilter: strength => strength >= 400,
})
$lastPunchStrength.on(punch, (_, strength) => strength)
// Each store update should trigger event `veryStrongHit`
forward({from: $lastPunchStrength, to: veryStrongHit})
// Watch on store prints initial state
$lastPunchStrength.watch(strength => console.log('Strength: %skg', strength))
// => Strength: 0kg
veryStrongHit.watch(strength => {
console.log('Wooow! It was very strong! %skg', strength)
})
punch(200) // updateFilter prevented update
punch(300) // Same here. Note: store don't updates, value is the same `0`
punch(500) // Yeeah! updateFilter allows to update store value
// => Strength: 500kg
// => Wooow! It was very strong! 500kg
punch(100) // Also nothing
Example with serialize: ignore
import {
createEvent,
createStore,
forward,
serialize,
fork,
allSettled,
} from 'effector'
const readPackage = createEvent()
const $name = createStore('')
const $version = createStore(0, {serialize: 'ignore'})
$name.on(readPackage, (_, {name}) => name)
$version.on(readPackage, (_, {version}) => version)
// Watchers always called for scoped changes
$name.watch(name => console.log("name '%s'", name))
$version.watch(version => console.log('version %s', version))
// => name ''
// => version 0
// Please, note, `fork()` call doesn't trigger watches
// In the opposit of `hydrate()` call
const scope = fork()
// By default serialize saves value only for the changed stores
// Review `onlyChanges` option https://effector.dev/docs/api/effector/serialize
const values = serialize(scope)
console.log(values)
// => {}
// Let's change our stores
await allSettled(readPackage, {
scope,
params: {name: 'effector', version: 22},
})
// => name 'effector'
// => version 22
const actualValues = serialize(scope)
console.log(actualValues)
// => {n74m6b: "effector"}
// This is because `$version` store has `serialize: ignore`
Example with custom serialize configuration
import {createEvent, createStore, serialize, fork, allSettled} from 'effector'
const saveDate = createEvent()
const $date = createStore<null | Date>(null, {
// Date object is automatically serialized to ISO date string by JSON.stringify
// but it is not parsed to Date object by JSON.parse
// which will lead to a mismatch during server side rendering
//
// Custom `serialize` config solves this issue
serialize: {
write: dateOrNull => (dateOrNull ? dateOrNull.toISOString() : dateOrNull),
read: isoStringOrNull =>
isoStringOrNull ? new Date(isoStringOrNull) : isoStringOrNull,
},
}).on(saveDate, (_, p) => p)
const serverScope = fork()
await allSettled(saveDate, {scope: serverScope, params: new Date()})
const serverValues = serialize(serverScope)
// `serialize.write` of `$date` store is called
console.log(serverValues)
// => { nq1e2rb: "2022-11-05T15:38:53.108Z" }
// Date object saved as ISO string
const clientScope = fork({values: serverValues})
// `serialize.read` of `$date` store is called
const currentValue = clientScope.getState($date)
console.log(currentValue)
// => Date 11/5/2022, 10:40:13 PM
// ISO date string is parsed back to Date object