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 an effect is triggered.
It will replace the previous function inside (if any).
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.
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 does send transformed data into source event. Works kind of like reverse .map. In the case of .prepend data transforms before the original event occurs and in the case of .map, data transforms after original event occurred.
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 triggered when handler is resolved.
Arguments
Event triggered with result of effect execution:
result(Done): A result of the resolved handler
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 triggered when handler is rejected or throws error.
Arguments
Event triggered with error thrown by effect:
error(Fail): An error thrown by handler
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 triggered when handler is resolved.
Arguments
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 triggered when handler is rejected or throws error.
Arguments
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 triggered when handler is resolved, rejected or throws error.
Arguments
Event 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 a 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