Это руководство охватывает шаги, необходимые для перехода на 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. Перевод документации на другие языки осуществляется сообществом по мере наличия сил и желания.
Помните, что переведенные статьи могут быть неактуальными, поэтому для получения наиболее точной и актуальной информации рекомендуем использовать оригинальную англоязычную версию документации.