Effect
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
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([]) // Default state // add reducer for fetchUserFx.doneData event (triggered when handler resolved) .on(fetchUserFx.doneData, (users, user) => [...users, user])
// subscribe to handler resolvefetchUserFx.done.watch(({result, params}) => { console.log(params) // => {id: 1} console.log(result) // => resolved value})
// subscribe to handler reject or throw errorfetchUserFx.fail.watch(({error, params}) => { console.error(params) // => {id: 1} console.error(error) // => rejected value})
// you can replace function anytimefetchUserFx.use(anotherHandler)
// call effect with your paramsfetchUserFx({id: 1})
// handle promiseconst data = await fetchUserFx({id: 2})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
.usemethod orhandlerproperty in createEffect, otherwise the error "no handler used in %effect name%" will appear in the console
Arguments
handler(Function): Function, that receives the first argument passed to an effect call.
Returns
(Effect): The same effect
Example
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'})// => fetchUserRepos called with {name: 'zerobias'}watch(watcher)
Subscribe to effect calls.
Formulae
const unwatch = effect.watch(fn)- Call
fnon eacheffectcall, pass payload ofeffectas argument tofn - When
unwatchis called, stop callingfn
Arguments
watcher(Watcher): A function that receivespayload.
Returns
Subscription: Unsubscribe function.
Example
import {createEffect} from 'effector'
const effectFx = createEffect({ handler: value => value,})
const unsubscribe = effectFx.watch(payload => { console.log('called with', payload) unsubscribe()})
effectFx(10) // => called with 10effectFx(20) // nothing, cause watcher unsubscribedprepend(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
const event = effect.prepend(fn)- When
eventis triggered - Call
fnwith payload fromevent - Call
effectwith result offn()
Arguments
fn(Function): A function that receivespayload, 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
const handlerA = () => 'A'const handlerB = () => 'B'
const fx = createEffect({handler: handlerA})
console.log(fx.use.getCurrent() === handlerA)// => true
fx.use(handlerB)console.log(fx.use.getCurrent() === handlerB)// => trueEffect Properties
doneData
Event, which is triggered with result of the effect execution:
Event triggered when handler is resolved.
Example
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) // => Done with result 3failData
Event, which is triggered with error thrown by the effect:
Event triggered when handler is rejected or throws error.
Example
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) // => Fail with error 1done
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
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) // => Done with params 2 and result 3fail
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
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) // => Fail with params 2 and error 1finally
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 (doneorfail)params(Params): An argument passed to effect callerror(Fail): An error catched from the handlerresult(Done): A result of the resolved handler
Example
import {createEffect} from 'effector'
const fetchApiFx = createEffect({ handler: ms => new Promise(resolve => setTimeout(resolve, ms, `${ms} ms`)),})
fetchApiFx.finally.watch(console.log)
fetchApiFx(100)// if resolved// => {status: 'done', result: '100 ms', params: 100}
// if rejected// => {status: 'fail', error: Error, params: 100}pending
Store will update when done or fail are triggered.
Store contains true value until the effect is resolved or rejected.
Example
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)It's a shorthand for common use case
import {createEffect, createStore} from 'effector'
const fetchApiFx = createEffect()
//now you can use fetchApiFx.pending insteadconst 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
import {createEffect} from 'effector'
const fx = createEffect({ handler: () => new Promise(rs => setTimeout(rs, 500)),})
fx.inFlight.watch(amount => { console.log('in-flight requests:', amount)})// => 0
const req1 = fx()// => 1
const req2 = fx()// => 2
await Promise.all([req1, req2])
// => 1// => 0
Effector