Bu sahifa hali tarjima qilinmagan

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

Standart til uchun tarkibni ko'rsatadi.

Reactivity in Effector

Reactivity is a fundamental concept in Effector that allows data to be automatically updated when its dependencies change. Instead of manually managing updates, you describe the relationships between different parts of your application, and Effector takes care of their synchronization.

What is Reactivity?

At the core of reactivity lies the principle of automatic change propagation. When the value of one store changes, all parts of the application that depend on it are automatically updated.

import { createStore, createEvent, combine } from "effector";

const firstWordChanged = createEvent<string>();

const $firstWord = createStore("Imperative");
const $secondWord = createStore("Programming");

const $fullSentence = combine($firstWord, $secondWord, (firstWord, secondWord) => {
  return `${firstWord} ${secondWord}`;
});

const $fullSentenceLength = $fullSentence.map((fullSentence) => fullSentence.length);

// Subscribe the store to event
$firstWord.on(firstWordChanged, (_, newWord) => newWord);

// Event call will update the store and all subscribers
firstWordChanged("Reactive");

In this example, when the state of the $firstWord store changes, both $fullSentence and $fullSentenceLength will automatically update as well, so you don’t need to manually update the values – Effector will handle this.

What Makes Effector Reactive?

  1. Automatic change propagation. When a store’s value changes, Effector automatically notifies all dependent units:
import { createStore } from "effector";

const $users = createStore<User[]>([]);
const $userCount = $users.map((users) => users.length);
const $hasUsers = $users.map((users) => users.length > 0);

// $userCount and $hasUsers will automatically update
// with any change to $users
  1. Declarative connections. Instead of imperatively describing what should happen and when, we declaratively describe the relationships between data:
import { sample, createStore, createEvent, createEffect } from "effector";

const formSubmitted = createEvent();
const $formData = createStore({ name: "", email: "" });
const submitToServerFx = createEffect(({ name, email }: { name: string; email: string }) => {
  // logic
});

sample({
  clock: formSubmitted,
  source: $formData,
  target: submitToServerFx,
});
  1. Predictable updates. Updates in Effector always occur in a specific order, making application behavior predictable:
import { createStore, createEvent, sample, createEffect } from "effector";

const $a = createStore(1);
const $b = createStore(2);
const updated = createEvent();

const updateFirstFx = createEffect(() => {
  // logic
});

const updateSecondFx = createEffect(() => {
  // logic
});

// Updates will happen in the order of declaration
sample({
  clock: updated,
  source: $a,
  target: updateFirstFx,
});

sample({
  clock: updateFirstFx.done,
  source: $b,
  target: updateSecondFx,
});

How Units Communicate

Effector manages dependencies between units (stores, events, and effects), ensuring the correct order of updates. When some units depend on others, Effector guarantees that changes propagate predictably:

import { createStore, createEvent, sample, createEffect } from "effector";

const fetchDataFx = createEffect(async () => {
  // api call
});

// Create units
const buttonClicked = createEvent();
const $isLoading = createStore(false);
const $error = createStore<Error | null>(null);

// Create dependencies
$isLoading
  .on(buttonClicked, () => true)
  // Reset state when loading completes
  .reset([fetchDataFx.done, fetchDataFx.fail]);

// Start loading on click
sample({
  clock: buttonClicked,
  target: fetchDataFx,
});

buttonClicked();

Real-life Example

Let’s take a look at an example of a search bar with automatic result updates:

import { createStore, createEvent, createEffect, sample } from "effector";

// Events and effects
const searchQueryChanged = createEvent<string>();

// 4
const searchFx = createEffect(async (query: string) => {
  const response = await fetch(`/api/search?q=${query}`);

  return response.json();
});

// States
const $searchQuery = createStore("");
const $searchResults = createStore([]);
const $isSearching = searchFx.pending;

// Connections
$searchQuery.on(searchQueryChanged, (_, query) => query); // 2
// Update results on successful search
// 5
$searchResults.on(searchFx.doneData, (_, results) => results);

// Start search when query changes
// 3
sample({
  clock: searchQueryChanged,
  source: $searchQuery,
  target: searchFx,
});

searchQueryChanged("qwerty"); // 1
  1. Somewhere in the application, searchQueryChanged was called.
  2. Update the $searchQuery store.
  3. Using sample, we declaratively call the target (searchFx) with data from the source.
  4. The searchFx effect executes.
  5. In case of successful searchFx effect, we update the data in the searchResults store.
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