Effect is a container for async function.
It can be safely used in place of the original async function.
Arguments# params (Params ): parameters passed to effect Returns# (Promise )
Example# Copy import { createEffect , createStore } from 'effector'
const fetchUserFx = createEffect ( {
async handler ( { id } ) {
const res = await fetch ( ` https://example.com/users/ ${ id } ` )
return res . json ( )
} ,
} )
const users = createStore ( [ ] )
. on ( fetchUserFx . doneData , ( users , user ) => [ ... users , user ] )
fetchUserFx . done . watch ( ( { result , params } ) => {
console . log ( params )
console . log ( result )
} )
fetchUserFx . fail . watch ( ( { error , params } ) => {
console . error ( params )
console . error ( error )
} )
fetchUserFx . use ( anotherHandler )
fetchUserFx ( { id : 1 } )
const data = await fetchUserFx ( { id : 2 } )
Try it
Effect Methods# use(handler)# Provides a function, which will be called when effect is triggered.
It will replace the previous function inside.
Note : You must provide a handler either through .use method or handler property in createEffect , otherwise the error "no handler used in %effect name% " will appear in the console
See also : Testing api calls with effects and stores
Arguments# handler (Function ): Function, that receives the first argument passed to an effect call. Returns# (Effect ): The same effect
Example# Copy const fetchUserReposFx = createEffect ( )
fetchUserReposFx . use ( async params => {
console . log ( 'fetchUserReposFx called with' , params )
const url = ` https://api.github.com/users/ ${ params . name } /repos `
const req = await fetch ( url )
return req . json ( )
} )
fetchUserReposFx ( { name : 'zerobias' } )
Try it
watch(watcher)# Subscribe to effect calls.
Formulae# Copy const unwatch = effect . watch ( fn )
Call fn on each effect call, pass payload of effect as argument to fn When unwatch is called, stop calling fn Arguments# watcher (Watcher ): A function that receives payload. Returns# Subscription : Unsubscribe function.
Example# Copy import { createEffect } from 'effector'
const effectFx = createEffect ( {
handler : value => value ,
} )
const unsubscribe = effectFx . watch ( payload => {
console . log ( 'called with' , payload )
unsubscribe ( )
} )
effectFx ( 10 )
effectFx ( 20 )
Try it
prepend(fn)# Creates an event, upon trigger it sends transformed data into the source event. Works kind of like reverse .map. In case of .prepend data transforms before the original event occurs and in the case of .map, data transforms after original event occurred .
Formulae# Copy const event = effect . prepend ( fn )
When event is triggered Call fn with payload from event Call effect with result of fn() Arguments# fn (Function ): A function that receives payload, should be pure . Returns# Event : New event.
use.getCurrent()# Returns current handler of effect. Useful for testing.
Returns# (Function ): Current handler, defined by handler property or via use call.
Example# Copy const handlerA = ( ) => 'A'
const handlerB = ( ) => 'B'
const fx = createEffect ( { handler : handlerA } )
console . log ( fx . use . getCurrent ( ) === handlerA )
fx . use ( handlerB )
console . log ( fx . use . getCurrent ( ) === handlerB )
Try it
Effect Properties# doneData# Event, which is triggered with result of the effect execution:
Event triggered when handler is resolved .
Example# Copy import { createEffect } from 'effector'
const effectFx = createEffect ( {
handler : value => Promise . resolve ( value + 1 ) ,
} )
effectFx . doneData . watch ( result => {
console . log ( 'Done with result' , result )
} )
effectFx ( 2 )
Try it
failData# Event, which is triggered with error thrown by the effect:
Event triggered when handler is rejected or throws error.
Example# Copy import { createEffect } from 'effector'
const effectFx = createEffect ( )
effectFx . use ( value => Promise . reject ( value - 1 ) )
effectFx . failData . watch ( error => {
console . log ( 'Fail with error' , error )
} )
effectFx ( 2 )
Try it
done# Event , which is triggered when handler is resolved .
Properties# Event triggered with object of params and result:
params (Params ): An argument passed to the effect callresult (Done ): A result of the resolved handler Example# Copy import { createEffect } from 'effector'
const effectFx = createEffect ( {
handler : value => Promise . resolve ( value + 1 ) ,
} )
effectFx . done . watch ( ( { params , result } ) => {
console . log ( 'Done with params' , params , 'and result' , result )
} )
effectFx ( 2 )
Try it
fail# Event , which is triggered when handler is rejected or throws error.
Properties# Event triggered with object of params and error:
params (Params ): An argument passed to effect callerror (Fail ): An error catched from the handler Example# Copy import { createEffect } from 'effector'
const effectFx = createEffect ( )
effectFx . use ( value => Promise . reject ( value - 1 ) )
effectFx . fail . watch ( ( { params , error } ) => {
console . log ( 'Fail with params' , params , 'and error' , error )
} )
effectFx ( 2 )
Try it
finally# Event, which is triggered when handler is resolved, rejected or throws error.
Properties# Event , which is triggered with object of status, params and error or result:
status (string ): A status of effect (done or fail)params (Params ): An argument passed to effect callerror (Fail ): An error catched from the handlerresult (Done ): A result of the resolved handler Example# Copy import { createEffect } from 'effector'
const fetchApiFx = createEffect ( {
handler : ms => new Promise ( resolve => setTimeout ( resolve , ms , ` ${ ms } ms ` ) ) ,
} )
fetchApiFx . finally . watch ( console . log )
fetchApiFx ( 100 )
Try it
pending# Store will update when done or fail are triggered.
Store contains true value until the effect is resolved or rejected.
Example# Copy import React from 'react'
import { createEffect } from 'effector'
import { useStore } from 'effector-react'
const fetchApiFx = createEffect ( {
handler : ms => new Promise ( resolve => setTimeout ( resolve , ms ) ) ,
} )
fetchApiFx . pending . watch ( console . log )
const Loading = ( ) => {
const loading = useStore ( fetchApiFx . pending )
return < div > { loading ? 'Loading...' : 'Load complete' } < / div >
}
ReactDOM . render ( < Loading / > , document . getElementById ( 'root' ) )
fetchApiFx ( 3000 )
Try it
It's a shorthand for common use case
Copy import { createEffect , createStore } from 'effector'
const fetchApiFx = createEffect ( )
const isLoading = createStore ( false )
. on ( fetchApiFx , ( ) => true )
. on ( fetchApiFx . done , ( ) => false )
. on ( fetchApiFx . fail , ( ) => false )
inFlight# Store which show how many effect calls aren't settled yet. Useful for rate limiting.
Example# Copy import { createEffect } from 'effector'
const fx = createEffect ( {
handler : ( ) => new Promise ( rs => setTimeout ( rs , 500 ) ) ,
} )
fx . inFlight . watch ( amount => {
console . log ( 'in-flight requests:' , amount )
} )
const req1 = fx ( )
const req2 = fx ( )
await Promise . all ( [ req1 , req2 ] )
Try it