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