createEffect

import { createEffect } from "effector";

const effectFx = createEffect();

Method for creating effects. Returns a new effect.

How to Create Effects

The createEffect method supports several ways to create effects:

  1. With a handler - this is the simplest way.
  2. With configuration.
  3. Without a handler, which can be set later using the .use(handler) method.

With Handler

  • Type
createEffect<Params, Done, Fail = Error>(
  handler: (params: Params) => Done | Promise<Done>,
): Effect<Params, Done, Fail>
  • Example
import { createEffect } from "effector";

const fetchUserReposFx = createEffect(async ({ name }) => {
  const url = `https://api.github.com/users/${name}/repos`;
  const req = await fetch(url);
  return req.json();
});

fetchUserReposFx.done.watch(({ params, result }) => {
  console.log(result);
});

await fetchUserReposFx({ name: "zerobias" });

With Configuration

The name field is used to improve error messages and debugging.

  • Type
export function createEffect<Params, Done, Fail = Error>(config: {
  name?: string;
  handler?: (params: Params) => Promise<Done> | Done;
}): Effect<Params, Done, Fail>;
  • Example
import { createEffect } from "effector";

const fetchUserReposFx = createEffect({
  name: "fetch user repositories",
  async handler({ name }) {
    const url = `https://api.github.com/users/${name}/repos`;
    const req = await fetch(url);
    return req.json();
  },
});

await fetchUserReposFx({ name: "zerobias" });

Without Handler

Most commonly used for testing. More detailed information.

use is an anti-pattern

Try to avoid using .use(), as it’s an anti-pattern and degrades type inference.

  • Example
import { createEffect } from "effector";

const fetchUserReposFx = createEffect();

fetchUserReposFx.use(async ({ name }) => {
  const url = `https://api.github.com/users/${name}/repos`;
  const req = await fetch(url);
  return req.json();
});

await fetchUserReposFx({ name: "zerobias" });

Examples

  • Updating state on effect completion:
import { createStore, createEffect } from "effector";

interface Repo {
  // ...
}

const $repos = createStore<Repo[]>([]);

const fetchUserReposFx = createEffect(async (name: string) => {
  const url = `https://api.github.com/users/${name}/repos`;
  const req = await fetch(url);
  return req.json();
});

$repos.on(fetchUserReposFx.doneData, (_, repos) => repos);

$repos.watch((repos) => {
  console.log(`${repos.length} repos`);
});
// => 0 repos

await fetchUserReposFx("zerobias");
// => 26 repos

Run example

  • Watching effect state:
import { createEffect } from "effector";

const fetchUserReposFx = createEffect(async ({ name }) => {
  const url = `https://api.github.com/users/${name}/repos`;
  const req = await fetch(url);
  return req.json();
});

fetchUserReposFx.pending.watch((pending) => {
  console.log(`effect is pending?: ${pending ? "yes" : "no"}`);
});

fetchUserReposFx.done.watch(({ params, result }) => {
  console.log(params); // {name: 'zerobias'}
  console.log(result); // resolved value, result
});

fetchUserReposFx.fail.watch(({ params, error }) => {
  console.error(params); // {name: 'zerobias'}
  console.error(error); // rejected value, error
});

fetchUserReposFx.finally.watch(({ params, status, result, error }) => {
  console.log(params); // {name: 'zerobias'}
  console.log(`handler status: ${status}`);

  if (error) {
    console.log("handler rejected", error);
  } else {
    console.log("handler resolved", result);
  }
});

await fetchUserReposFx({ name: "zerobias" });

Run example

Common errors

Below is a list of possible errors you may encounter when working with effects:

Contributors