import { split } from "effector";
Выберите один из кейсов по заданным условиям. Эта функция “разделяет” исходный юнит на несколько событий, которые срабатывают, когда полезная нагрузка соответствует их условиям. Работает как сопоставление с образцом для значений полезной нагрузки и внешних сторов.
Режимы
“Case” режим
Режим, в котором кейс выбирается его имени. Кейс может быть выбран из данных в source
с помощью функции кейса или из внешнего стора кейса, которое хранит текущее имя кейса. После выбора данные из source
будут отправлены в соответствующий cases[fieldName]
(если он есть), если ни одно из полей не совпадает, то данные будут отправлены в cases.__
(если он есть).
Смотрите также:
Режим сопоставления
Режим, в котором каждый кейс последовательно сопоставляется с сторами и функциями в полях объекта match
.
Если одно из полей получает true
из значения стора или возврата функции, то данные из source
будут отправлены в соответствующий cases[fieldName]
(если он есть), если ни одно из полей не совпадает, то данные будут отправлены в cases.__
(если он есть).
Смотрите также:
Стор кейса
Store со строкой, который будет использоваться для выбора итогового кейса по его имени. Размещается непосредственно в поле match
.
split({
source: Unit<T>
// стор кейса
match: Store<'first' | 'second'>,
cases: {
first: Unit<T> | Unit<T>[],
second: Unit<T> | Unit<T>[],
__?: Unit<T> | Unit<T>[]
}
})
Функция кейса
Функция, возвращающая строку, которая будет вызвана со значением из source
для выбора итогового кейса по его имени. Размещается непосредственно в поле match
, должна быть чистой.
split({
source: Unit<T>
// функция кейса
match: (value: T) => 'first' | 'second',
cases: {
first: Unit<T> | Unit<T>[],
second: Unit<T> | Unit<T>[],
__?: Unit<T> | Unit<T>[]
}
})
Стор сопоставления
Boolean
store, который указывает, следует ли выбрать конкретный кейс или попробовать следующий. Размещается в полях объекта match
, может быть смешано с функциями сопоставления.
split({
source: Unit<T>
match: {
// стор сопоставления
first: Store<boolean>,
second: Store<boolean>
},
cases: {
first: Unit<T> | Unit<T>[],
second: Unit<T> | Unit<T>[],
__?: Unit<T> | Unit<T>[]
}
})
Функция сопоставления
Стор кейса, функция кейса и стор сопоставления поддерживаются с effector 21.8.0
Функция, возвращающая boolean
значение, которое указывает, следует ли выбрать конкретный кейс или попробовать следующий. Размещается в полях объекта match
, может быть смешано с store сопоставления, должна быть чистой.
split({
source: Unit<T>
match: {
// функция сопоставления
first: (value: T) => boolean,
second: (value: T) => boolean
},
cases: {
first: Unit<T> | Unit<T>[],
second: Unit<T> | Unit<T>[],
__?: Unit<T> | Unit<T>[]
}
})
Методы
split({ source, match, cases })
Формула
split({ source, match, cases });
split({
source: Unit<T>
// функция кейса
match: (data: T) => 'a' | 'b',
cases: {
a: Unit<T> | Unit<T>[],
b: Unit<T> | Unit<T>[],
__?: Unit<T> | Unit<T>[]
}
})
split({
source: Unit<T>
// стор кейса
match: Store<'a' | 'b'>,
cases: {
a: Unit<T> | Unit<T>[],
b: Unit<T> | Unit<T>[],
__?: Unit<T> | Unit<T>[]
}
})
split({
source: Unit<T>
match: {
// функция сопоставления
a: (data: T) => boolean,
// стор сопоставления
b: Store<boolean>
},
cases: {
a: Unit<T> | Unit<T>[],
b: Unit<T> | Unit<T>[],
__?: Unit<T> | Unit<T>[]
}
})
Аргументы
source
: Юнит, который будет запускать вычисления вsplit
match
: Одиночное store со строкой, одиночная функция, возвращающая строку или объект с boolean сторами и функциями, возвращающими boolean значениеcases
: Объект с юнитами или массивами юнитов, в которые будут переданы данные изsource
после выбора кейса
Возвращает
void
Примеры
Базовый
import { split, createEffect, createEvent } from "effector";
const messageReceived = createEvent();
const showTextPopup = createEvent();
const playAudio = createEvent();
const reportUnknownMessageTypeFx = createEffect(({ type }) => {
console.log("неизвестное сообщение:", type);
});
split({
source: messageReceived,
match: {
text: (msg) => msg.type === "text",
audio: (msg) => msg.type === "audio",
},
cases: {
text: showTextPopup,
audio: playAudio,
__: reportUnknownMessageTypeFx,
},
});
showTextPopup.watch(({ value }) => {
console.log("новое сообщение:", value);
});
messageReceived({
type: "text",
value: "Привет",
});
// => новое сообщение: Привет
messageReceived({
type: "image",
imageUrl: "...",
});
// => неизвестное сообщение: image
Прямое сопоставление
Вы также можете сопоставлять напрямую с API хранилища:
import { split, createStore, createEvent, createApi } from "effector";
const messageReceived = createEvent();
const $textContent = createStore([]);
split({
source: messageReceived,
match: {
text: (msg) => msg.type === "text",
audio: (msg) => msg.type === "audio",
},
cases: createApi($textContent, {
text: (list, { value }) => [...list, value],
audio: (list, { duration }) => [...list, `аудио ${duration} мс`],
__: (list) => [...list, "неизвестное сообщение"],
}),
});
$textContent.watch((messages) => {
console.log(messages);
});
messageReceived({
type: "text",
value: "Привет",
});
// => ['Привет']
messageReceived({
type: "image",
imageUrl: "...",
});
// => ['Привет', 'неизвестное сообщение']
messageReceived({
type: "audio",
duration: 500,
});
// => ['Привет', 'неизвестное сообщение', 'аудио 500 мс']
Кейс с массивами юнитов
import { createEffect, createEvent, createStore, sample, split } from "effector";
const $verificationCode = createStore("12345");
const $error = createStore("");
const modalToInputUsername = createEvent();
const modalToAuthorizationMethod = createEvent();
const checkVerificationCodeFx = createEffect((code) => {
throw "500";
});
sample({
clock: verificationCodeSubmitted,
source: $verificationCode,
target: checkVerificationCodeFx,
});
split({
source: checkVerificationCodeFx.failData,
match: (value) => (["400", "410"].includes(value) ? "verificationCodeError" : "serverError"),
cases: {
verificationCodeError: $verificationCodeError,
serverError: [$error, modalToAuthorizationMethod],
},
});
$error.updates.watch((value) => console.log("ОШИБКА: " + value));
modalToAuthorizationMethod.watch(() =>
console.log("Модальное окно с содержимым метода авторизации."),
);
// => ОШИБКА: 500
// => Модальное окно с содержимым метода авторизации.
split(source, match)
Формула
split(source, match);
Аргументы
source
: Юнит, который будет запускать вычисления вsplit
match
(Объект): Схема кейсов, которая использует имена результирующих событий как ключи и функцию сопоставления*((value) => Boolean)*
Возвращает
(Объект) – Объект, имеющий ключи, определенные в аргументе match
, плюс __
(два подчеркивания) – который обозначает кейс по умолчанию (если ни одно из условий не выполнено).
Примеры
Базовый
import { createEvent, split } from "effector";
const message = createEvent();
const messageByAuthor = split(message, {
bob: ({ user }) => user === "bob",
alice: ({ user }) => user === "alice",
});
messageByAuthor.bob.watch(({ text }) => {
console.log("[bob]: ", text);
});
messageByAuthor.alice.watch(({ text }) => {
console.log("[alice]: ", text);
});
message({ user: "bob", text: "Привет" });
// => [bob]: Привет
message({ user: "alice", text: "Привет, bob" });
// => [alice]: Привет, bob
/* кейс по умолчанию, срабатывает, если ни одно из условий не выполнено */
const { __: guest } = messageByAuthor;
guest.watch(({ text }) => {
console.log("[гость]: ", text);
});
message({ user: "незарегистрированный", text: "привет" });
// => [гость]: привет
Только первое выполненное сопоставление вызовет результирующее событие
Другой пример
import { createEvent, split } from "effector";
const message = createEvent();
const { short, long, medium } = split(message, {
short: (m) => m.length <= 5,
medium: (m) => m.length > 5 && m.length <= 10,
long: (m) => m.length > 10,
});
short.watch((m) => console.log(`короткое сообщение '${m}'`));
medium.watch((m) => console.log(`среднее сообщение '${m}'`));
long.watch((m) => console.log(`длинное сообщение '${m}'`));
message("Привет, Боб!");
// => длинное сообщение 'Привет, Боб!'
message("Привет!");
// => короткое сообщение 'Привет!'
split({ source, clock?, match, cases })
Работает так же, как split с кейсами, однако вычисления в split
будут запущены после срабатывания clock
.
Формула
split({source, clock?, match, cases})
Аргументы
TBD
Примеры
import { createStore, createEvent, createEffect, split } from "effector";
const options = ["save", "delete", "forward"];
const $message = createStore({ id: 1, text: "Принесите мне чашку кофе, пожалуйста!" });
const $mode = createStore("");
const selectedMessageOption = createEvent();
const saveMessageFx = createEffect(() => "save");
const forwardMessageFx = createEffect(() => "forward");
const deleteMessageFx = createEffect(() => "delete");
$mode.on(selectedMessageOption, (mode, opt) => options.find((item) => item === opt) ?? mode);
split({
source: $message,
clock: selectedMessageOption,
match: $mode,
cases: {
save: saveMessageFx,
delete: deleteMessageFx,
forward: forwardMessageFx,
},
});
selectedMessageOption("delet"); // ничего не происходит
selectedMessageOption("delete");
Документация на английском языке - самая актуальная, поскольку её пишет и обновляет команда effector. Перевод документации на другие языки осуществляется сообществом по мере наличия сил и желания.
Помните, что переведенные статьи могут быть неактуальными, поэтому для получения наиболее точной и актуальной информации рекомендуем использовать оригинальную англоязычную версию документации.