Это руководство охватывает шаги, необходимые для перехода на Effector 23 с предыдущей версии. В этом релизе несколько функций были объявлены устаревшими:
- Операторы
forward
иguard
- Опция
greedy
вsample
была переименована вbatch
- Типы “производных” и “вызываемых” юнитов теперь официально разделены
- Возможность использовать
undefined
как магическое значение “пропуска” в редьюсерах
Устаревание forward
и guard
Эти операторы довольно старые и прошли через множество релизов Effector.
Но все их случаи использования уже покрываются оператором sample
, поэтому пришло время их убрать. Вы увидите предупреждение об устаревании в консоли для каждого вызова этих операторов в вашем коде.
Вы можете мигрировать с обоих операторов, используя официальный ESLint-плагин Effector, который имеет правила no-forward
и no-guard
со встроенной функцией авто-исправления.
Переименование greedy
в batch
Оператор sample
имел опцию greedy
для отключения батчинга обновлений в редких крайних случаях.
Но название “greedy” не было очевидным для пользователей, поэтому оно было переименовано в batch
, и его сигнатура была инвертирована.
Вы увидите предупреждение об устаревании в консоли для каждого использования опции greedy
в вашем коде.
Вы можете мигрировать с одного на другое, просто выполнив “Найти и заменить” от greedy: true
к batch: false
в IDE.
Разделение типов для производных и вызываемых юнитов
Производные юниты теперь полностью отделены от “вызываемых/записываемых”:
- Основные фабрики
createEvent
иcreateStore
теперь возвращают типыEventCallable
иStoreWritable
(поскольку вы можете вызывать и записывать в эти юниты в любой момент). - Методы и операторы, такие как
unit.map(...)
илиcombine(...)
, теперь возвращают типыEvent
иStore
, которые являются “только для чтения”, т.е. вы можете использовать их только какclock
илиsource
, но не какtarget
. - Тип
EventCallable
может быть присвоен типуEvent
, но не наоборот, то же самое для сторов. - Также есть исключения в рантайме для несоответствия типов.
Скорее всего, вам не нужно будет ничего делать, вы просто получите улучшенные типы.
Но у вас могут возникнуть проблемы с внешними библиотеками, которые еще не обновлены до Effector 23:
- Большинство библиотек просто принимают юниты как
clock
иsource
– в таком случае всё в порядке. - Если какой-то оператор из внешней библиотеки принимает юнит как
target
, вы всё равно увидите старый добрый типEvent
в этом случае, поэтому у вас не будет ошибки типа, даже если на самом деле есть проблема. - Если какая-то фабрика возвращает событие, которое вы должны вызывать в своем коде, то вы получите ошибку типа, и вам нужно будет привести это событие к типу
EventCallable
.
Если вы столкнулись с любым из этих случаев, просто создайте issue в репозитории этой библиотеки с запросом на поддержку версии Effector 23. Владельцы проекта увидят соответствующие ошибки типов в своем исходном коде и тестах, как только обновят Effector в своем репозитории.
Если у вас есть эти проблемы в ваших собственных фабриках или библиотеках, то вы уже должны видеть соответствующие ошибки типов в исходном коде вашей библиотеки.
Просто замените Event
на EventCallable
, Store
на StoreWritable
или Unit
на UnitTargetable
везде, где это уместно (т.е. вы собираетесь вызывать или записывать в эти юниты каким-то образом).
Устаревание магического undefined
для пропуска
В Effector есть старая функция: undefined
используется как “магическое” значение для пропуска обновлений в редьюсерах в редких случаях, например:
const $value = createStore(0).on(newValueReceived, (_oldValue, newValue) => newValue);
☝️ если newValue
равно undefined
, то обновление будет пропущено.
Идея сделать каждый маппер и редьюсер работающим как своего рода filterMap
считалась полезной в ранних версиях Effector, но очень редко используется правильно, а также сбивает с толку и отвлекает, поэтому она должна быть устаревшей и удалена.
Для этого каждая фабрика сторов теперь поддерживает специальную настройку skipVoid
, которая контролирует, как именно стор должен обрабатывать значение undefined
. Если установлено false
– стор будет использовать undefined
как значение.
Если установлено true
(устаревшее), стор будет интерпретировать undefined
как команду “пропустить обновление” и ничего не делать.
Вы увидите предупреждение для каждого возврата undefined
в ваших мапперах или редьюсерах в вашем коде, с требованием указать явную настройку skipVoid
для вашего стора.
Если вы хотите пропустить обновление стора в определенных случаях, то лучше явно вернуть предыдущее состояние, когда это возможно.
Рекомендуется использовать {skipVoid: false}
всегда, чтобы вы могли использовать undefined
как обычное значение.
Если вам действительно нужно undefined
как “магическое значение пропуска” – тогда вы можете использовать {skipVoid: true}
, чтобы сохранить текущее поведение. Вы всё равно получите предупреждение об устаревании, но только одно для объявления вместо одного для каждого такого обновления.
Настройка skipVoid
временная и нужна только как способ правильно устареть от этой функции в Effector. В Effector 24 skipVoid
сам будет устаревшим, а затем удален.
useStore
и useEvent
заменены на useUnit
в effector-react
Мы объединили два старых хука в один, его преимущество в том, что вы можете передать много юнитов сразу, и он батчит все обновления сторов в одно обновление.
Можно безопасно заменить вызовы старых хуков на новый:
const Component = () => {
const foo = useStore($foo);
const bar = useStore($bar);
const onSubmit = useEvent(triggerSubmit);
};
Превращается в:
const Component = () => {
const foo = useUnit($foo);
const bar = useUnit($bar);
const onSubmit = useUnit(triggerSubmit);
};
Или короче:
const Component = () => {
const [foo, bar, onSubmit] = useUnit([$foo, $bar, triggerSubmit]);
};
Документация на английском языке - самая актуальная, поскольку её пишет и обновляет команда effector. Перевод документации на другие языки осуществляется сообществом по мере наличия сил и желания.
Помните, что переведенные статьи могут быть неактуальными, поэтому для получения наиболее точной и актуальной информации рекомендуем использовать оригинальную англоязычную версию документации.