batch# Will delay informing any reactions or components about write operations during the end of the call
Copy batch ( ( ) => {
store . value ++ ;
store . value ++ ;
} ) ;
dontWatch# Will not watch any read operations during provided callback
Copy dontWatch ( ( ) => {
performExpensiveOperation ( store ) ;
} ) ;
sync# Will make any store changes performed during the call ignore schedulers of watch reactions, even if they have any
Copy const myStore = store ( { count : 1 } ) ;
watch (
( ) => {
console . log ( myStore . count ) ;
} ,
{
scheduler : 'async' ,
} ,
) ;
sync ( ( ) => {
myStore . count ++ ;
} ) ;
Read operations during sync call are still batched
syncEvery# Will flush each change to the store made during this callback instantly, ignoring any reactions schedulers
Copy const myStore = store ( { count : 1 } ) ;
watch (
( ) => {
console . log ( myStore . count ) ;
} ,
{
scheduler : 'async' ,
} ,
) ;
sync ( ( ) => {
myStore . count ++ ;
myStore . count ++ ;
} ) ;
allowNestedWatch# Explicit flag required to call watch
during another watch
reaction. If trying to call watch
inside another watch
outside of this callback, error will be thrown
Copy import { allowNestedWatch } from 'statek' ;
watch ( ( ) => {
const stop = allowNestedWatch ( ( ) =>
watch ( ( ) => {
} ) ,
) ;
} ) ;
createAsyncScheduler# Allows creating custom async scheduler. Useful if we want to wrap all reactions calls inside 3rd party callbacks such as React's batched updates.
By default, all reactions in @statek/react
are batched and wrapped inside react batched updates so using it manually is not required.
selector# sync# Creates new selector (which does not accept any input arguments)
Copy const myStore = store ( { count : 1 } ) ;
const isBig = selector ( ( ) => myStore . count > 10 ) ;
isBig . value ;
watch ( ( ) => {
console . log ( isBig . value ) ;
} ) ;
async# Copy const myStore = store ( { count : 1 } ) ;
const isBig = selector ( async ( ) => {
return api . isNumberBig ( myStore . count ) ;
} ) ;
isBig . value ;
watch ( ( ) => {
console . log ( isBig . value ) ;
} ) ;
watch ( async ( ) => {
const result = await isBig . promise ;
console . log ( result ) ;
} ) ;
selectorFamily# Creates new 'family' of selectors which can accept any amount of input arguments
Copy const todos = store ( {
list : [
{ id : 1 , name : 'A' , status : 'done' , owner : 'Anna' } ,
{ id : 2 , name : 'B' , status : 'todo' , owner : 'Tom' } ,
] ,
} ) ;
const completedTodosCount = selector ( ( ) => {
return todos . list . filter ( todo => todo . status === 'done' ) . length ;
} ) ;
And now use this selector value in 2 code examples we've written above:
Copy const CompletedTodosCount = view ( ( ) => {
return < div > Count of completed todos is { completedTodosCount . value } </ div > ;
} ) ;
warmSelectors# Will request all provided selectors to prepare their values if they're not ready yet.
If called during watch reaction or react component render, will also group any async selectors suspense 's into single one
Copy const todoComments = selectorFamily ( async todoId => {
const comments = await todoApi . getComments ( todoId ) ;
return comments ;
} ) ;
const todoAttachments = selectorFamily ( async todoId => {
const attachments = await todoApi . getAttachments ( todoId ) ;
return attachments ;
} ) ;
Copy import { warmSelectors } from 'statek' ;
const OpenedTodoInfo = view ( ( ) => {
const { openedTodoId } = todos ;
if ( ! openedTodoId ) {
return ;
}
warmSelectors ( todoComments ( openedTodoId ) , todoAttachments ( openedTodoId ) ) ;
const comments = todoComments ( openedTodoId ) . value ;
const attachments = todoAttachments ( openedTodoId ) . value ;
return (
< div >
We have $ { comments . length } ) comments and $ { attachments . length } attachments
</ div >
) ;
} ) ;
SelectorOptions# Copy interface SelectorOptions {
name ? : string ;
lazy ? : boolean ;
updateStrategy ? : UpdateStrategy ;
}
UpdateStrategy# Copy type UpdateStrategy = 'silent' | 'reset' ;
getStoreRaw# Will return raw, not observable object corresponding to observable counterpart
Copy const input = { count : 1 } ;
const myStore = store ( input ) ;
getStoreRaw ( myStore ) === input ;
isStore# Will return true if provided object is observable store
Copy const myStore = store ( input ) ;
isStore ( myStore ) ;
store# Will create new observable store or return existing one for provided input.
Input can be either object or function returning object
Copy type StoreFactory < T extends object > = T | ( ( ) => T ) ;
function store < T > ( input : StoreFactory < T > ) : T ;
manualWatch# Copy function manualWatch < A extends any [ ] , R > (
lazyWatcher : ManualReactionCallback < A , R > ,
onWatchedChange ? : ( ) => void ,
options ? : ReactionOptions ,
) : ManualReaction < A , R > ;
type ManualReaction < A extends any [ ] , R > = ManualReactionCallback < A , R > & {
stop ( ) : void ;
} ;
type ManualReactionCallback < A extends any [ ] , R > = ( ... args : A ) => R ;
Will create reaction that can be manually called.
First argument is reaction callback that we can manually call.
2nd argument is callback that will be called each time when any store value used in last call changed
Copy const callReaction = manualWatch (
multiplier => {
return myStore . count * multiplier ;
} ,
( ) => {
console . log ( 'any store value used by reaction changed!' ) ;
} ,
) ;
callReaction ( 2 ) ;
watch# Will create new reaction that automatically calls itself each time store values used during last call is changed
Copy function watch (
watchCallback : ReactionCallback ,
options ? : ReactionOptions ,
) : ( ) => void ;
Copy const myStore = store ( { count : 1 } ) ;
watch ( ( ) => {
console . log ( myStore . count ) ;
} ) ;
myStore . count ++ ;
myStore . count ++ ;
myStore . count ++ ;
watchAllChanges# Copy function watchAllChanges (
storePart : object ,
callback : ReactionCallback ,
options ? : ReactionOptions ,
) : ( ) => void ;
Requires 2 arguments. First is any store (any part of the store is store as well) and 2nd is callback that will be called every time any value of provided store changes
ReactionOptions# Copy interface ReactionOptions {
scheduler ? : SchedulerInput ;
context ? : any ;
name ? : string ;
onSilentUpdate ? : EventCallback < Promise < any >> ;
}
SchedulerInput# Copy type SchedulerInput = 'sync' | 'async' | ReactionScheduler ;
SchedulerInput# Copy type ReactionScheduler = (
reaction : ( ) ,
) => Promise < void > | void ;
createAsyncScheduler# Copy function createAsyncScheduler (
wrapper ? : ( task : Task ) => Promise < void > | void ,
) : ReactionScheduler ;
type Task = ( ) => void ;
Allows creating custom async scheduler tha
Copy import { unstable_batchedUpdates } from 'react-dom' ;
export const reactScheduler = createAsyncScheduler ( task => {
unstable_batchedUpdates ( ( ) => {
task ( ) ;
} ) ;
} ) ;
ReactionCallback# Copy type ReactionCallback = ( ) => void ;
ManualReactionCallback# Copy type ManualReactionCallback < A extends any [ ] , R > = ( ... args : A ) => R ;