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

Помните, что переведенные статьи могут быть неактуальными, поэтому для получения наиболее точной и актуальной информации рекомендуем использовать оригинальную англоязычную версию документации.

Соавторы