Bu sahifa hali tarjima qilinmagan

Tarjima qoshish uchun havola boyicha o'tib Pull Request oching (havolaga o'tish).

Standart til uchun tarkibni ko'rsatadi.

import { type Effect } from "effector";

Effect is a container for async function or any throwing function.

It can be safely used in place of the original async function.

Methods

.use(handler)

Provides a function, which will be called when the effect is triggered.

Formulae

effect.use(fn);
  • Set handler fn for effect
  • If effect already had an implementation at the time of the call, it will be replaced by a new one

Hint: current handler can be extracted with effect.use.getCurrent().

You must provide a handler either through .use method or handler property in createEffect, otherwise effect will throw with no handler used in _%effect name%_ error when effect will be called.

Arguments

  1. handler (Function): Function, that receives the first argument passed to an effect call.

Returns

(Effect): The same effect

Examples

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'}

Try it

.use.getCurrent()

Returns current handler of effect. Useful for testing.

Formulae

fn = effect.use.getCurrent();
  • Returns current handler fn for effect
  • If no handler was assigned to effect, default handler will be returned (that throws an error)

Hint: to set a new handler use effect.use(handler)

Returns

(Function): Current handler, defined by handler property or via .use call.

Examples

const handlerA = () => "A";
const handlerB = () => "B";

const fx = createEffect(handlerA);

console.log(fx.use.getCurrent() === handlerA);
// => true

fx.use(handlerB);
console.log(fx.use.getCurrent() === handlerB);
// => true

Try it

.watch(watcher)

Subscribe to effect calls.

Formulae

const unwatch = effect.watch(watcher);
  • Call watcher on each effect call, pass payload of effect as argument to watcher
  • When unwatch is called, stop calling watcher

Arguments

  1. watcher (Watcher): A function that receives payload.

Returns

Subscription: Unsubscribe function.

Examples

import { createEffect } from "effector";

const fx = createEffect((params) => params);

fx.watch((params) => {
  console.log("effect called with value", params);
});

await fx(10);
// => effect called with value 10

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

const event = effect.prepend(fn);
  • When event is triggered, call fn with payload from event, then trigger effect with the result of fn()
  • event will have EventCallable<T> type, so can be used as target in methods like sample()

Arguments

  1. fn (Function): A function that receives payload, should be pure.

Returns

Event: New event.

.map(fn)

Creates a new event, which will be called after the original effect is called, applying the result of a fn as a payload. It is a special function which allows you to decompose dataflow, extract or transform data.

Formulae

const second = first.map(fn);
  • When first is triggered, pass payload from first to fn
  • Trigger second with the result of the fn() call as payload
  • second event will have Event<T> type, so it CAN NOT be used as target in methods like sample()

Arguments

  1. fn (Function): A function that receives payload, should be pure.

Returns

Event: New event.

Examples

import { createEffect } from "effector";

const userUpdate = createEffect(({ name, role }) => {
  console.log(name, role);
});
const userNameUpdated = userUpdate.map(({ name }) => name); // you may decompose dataflow with .map() method
const userRoleUpdated = userUpdate.map(({ role }) => role.toUpperCase()); // either way you can transform data

userNameUpdated.watch((name) => console.log(`User's name is [${name}] now`));
userRoleUpdated.watch((role) => console.log(`User's role is [${role}] now`));

await userUpdate({ name: "john", role: "admin" });
// => User's name is [john] now
// => User's role is [ADMIN] now
// => john admin

Try it

Properties

You are not supposed to use parts of effect (like .done and .pending) as a target in sample (even though they are events and stores), since effect is a complete entity on its own. This behavior will not be supported.

In the examples below constant effect has this signature:

effect: Effect<Params, Done, Fail>;

.done Event

Event, which is triggered when handler is resolved.

Important

Do not manually call this event. It is an event that depends on effect.

Formulae

effect.done: Event<{ params: Params; done: Done }>;

Properties

Event triggered with an object of params and result:

  1. params (Params): An argument passed to the effect call
  2. result (Done): A result of the resolved handler

Examples

import { createEffect } from "effector";

const fx = createEffect((value) => value + 1);

fx.done.watch(({ params, result }) => {
  console.log("Call with params", params, "resolved with value", result);
});

await fx(2);
// => Call with params 2 resolved with value 3

Try it

.doneData Event

Event, which is triggered by the result of the effect execution.

Important

Do not manually call this event. It is an event that depends on the effect.

Formulae

effect.doneData: Event<Done>;
  • doneData is an event, that triggered when effect is successfully resolved with result from .done

Event triggered when handler is resolved.

Examples

import { createEffect } from "effector";

const fx = createEffect((value) => value + 1);

fx.doneData.watch((result) => {
  console.log(`Effect was successfully resolved, returning ${result}`);
});

await fx(2);
// => Effect was successfully resolved, returning 3

Try it

.fail Event

Event, which is triggered when handler is rejected or throws error.

Important

Do not manually call this event. It is an event that depends on effect.

Formulae

effect.fail: Event<{ params: Params; error: Fail }>;

Properties

Event triggered with an object of params and error:

  1. params (Params): An argument passed to effect call
  2. error (Fail): An error caught from the handler

Examples

import { createEffect } from "effector";

const fx = createEffect(async (value) => {
  throw Error(value - 1);
});

fx.fail.watch(({ params, error }) => {
  console.log("Call with params", params, "rejected with error", error.message);
});

fx(2);
// => Call with params 2 rejected with error 1

Try it

.failData Event

Event, which is triggered with error thrown by the effect.

Important

Do not manually call this event. It is an event that depends on effect.

Formulae

effect.failData: Event<Fail>;
  • failData is an event, that triggered when effect is rejected with error from .fail

Event triggered when handler is rejected or throws error.

Examples

import { createEffect } from "effector";

const fx = createEffect(async (value) => {
  throw Error(value - 1);
});

fx.failData.watch((error) => {
  console.log(`Execution failed with error ${error.message}`);
});

fx(2);
// => Execution failed with error 1

Try it

.finally Event

Event, which is triggered when handler is resolved, rejected or throws error.

Important

Do not manually call this event. It is an event that depends on effect.

Properties

type Success = { status: 'done'; params: Params; result: Done }
type Failure = { status: 'fail'; params: Params; error: Fail }

effect.finally: Event<Success | Failure>;

Properties

Event, which is triggered with an object of status, params and error or result:

  1. status (string): A status of effect (done or fail)
  2. params (Params): An argument passed to effect call
  3. error (Fail): An error caught from the handler
  4. result (Done): A result of the resolved handler

Examples

import { createEffect } from "effector";

const fetchApiFx = createEffect(async ({ time, ok }) => {
  await new Promise((resolve) => setTimeout(resolve, time));
  if (ok) return `${time} ms`;
  throw Error(`${time} ms`);
});

fetchApiFx.finally.watch((value) => {
  switch (value.status) {
    case "done":
      console.log("Call with params", value.params, "resolved with value", value.result);
      break;
    case "fail":
      console.log("Call with params", value.params, "rejected with error", value.error.message);
      break;
  }
});

await fetchApiFx({ time: 100, ok: true });
// => Call with params {time: 100, ok: true}
//    resolved with value 100 ms

fetchApiFx({ time: 100, ok: false });
// => Call with params {time: 100, ok: false}
//    rejected with error 100 ms

Try it

.pending Store

Store contains true when effect is called but not resolved yet. Useful to show loaders.

Important

Do not modify store value! It is derived store and should be in predictable state.

Formulae

effect.pending: Store<boolean>;
  • Store will update when done or fail are triggered
  • Store contains true value until the effect is resolved or rejected

Returns

DerivedStore: Store that represents current state of the effect

Examples

import React from "react";
import ReactDOM from "react-dom";
import { createEffect } from "effector";
import { useUnit } from "effector-react";

const fetchApiFx = createEffect((ms) => new Promise((resolve) => setTimeout(resolve, ms)));

fetchApiFx.pending.watch(console.log);

const Loading = () => {
  const loading = useUnit(fetchApiFx.pending);

  return <div>{loading ? "Loading..." : "Load complete"}</div>;
};

ReactDOM.render(<Loading />, document.getElementById("root"));

fetchApiFx(3000);

Try it

It’s property is a shorthand for common use case:

import { createEffect, createStore } from "effector";

const fetchApiFx = createEffect();

// now you can use fetchApiFx.pending instead
const $isLoading = createStore(false)
  .on(fetchApiFx, () => true)
  .on(fetchApiFx.done, () => false)
  .on(fetchApiFx.fail, () => false);

.inFlight Store

Shows how many effect calls aren’t settled yet. Useful for rate limiting.

Important

Do not modify $count value! It is derived store and should be in predictable state.

Formulae

effect.inFlight: Store<number>;
  • The store will be 0 if no calls of effect in pending state, its default state
  • On each call of effect state in the store will be increased
  • When effect resolves to any state(done or fail) state in the store will be decreased

Returns

DerivedStore: Store that represents count of the running effects

Examples

import { createEffect } from "effector";

const fx = createEffect(() => 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

Try it

Types

import { type EffectParams, type EffectResult, type EffectError } from "effector";

EffectParams<FX>

Allows to extract type of Params from effect.

const effect: Effect<Params, Done, Fail>;
type Params = EffectParams<typeof effect>;

EffectResult<FX>

Allows to extract type of result from effect.

const effect: Effect<Params, Done, Fail>;
type Done = EffectResult<typeof effect>;

EffectError<FX>

Allows to extract type of error from effect.

const effect: Effect<Params, Done, Fail>;
type Fail = EffectError<typeof effect>;
Tarjima jamiyat tomonidan qollanilyapti

Ingliz tilidagi hujjatlar eng dolzarb hisoblanadi, chunki u effector guruhi tomonidan yozilgan va yangilanadi. Hujjatlarni boshqa tillarga tarjima qilish jamiyat tomonidan kuch va istaklar mavjud bo'lganda amalga oshiriladi.

Esda tutingki, tarjima qilingan maqolalar yangilanmasligi mumkin, shuning uchun eng aniq va dolzarb ma'lumot uchun hujjatlarning asl inglizcha versiyasidan foydalanishni tavsiya etamiz.

Hammualliflar