Исправление ошибок
Основные ошибки
store: undefined is used to skip updates. To allow undefined as a value provide explicit { skipVoid: false } option
Эта ошибка сообщает вам о том, что вы пытаетесь передать в ваш стор значение undefined
, что, возможно, является некорректным поведением.
Если вам действительно нужно передать в ваш стор значение undefined
, то вам надо вторым аргументом в createStore
передать объект со свойством skipVoid: false
.
const $store = createStore(0, { skipVoid: false,});
no handler used in [effect name]
Эта ошибка возникает при вызове эффекта без обработчика. Убедитесь, что вы передали обработчик в метод createEffect
при создании, или позже при использовании метода .use(handler)
.
serialize: One or more stores dont have sids, their values are omitted
До версии 23.3.0 эта ошибка также известна как: There is a store without sid in this scope, its value is omitted
.
Эта ошибка часто встречается при работе с SSR, она связана с тем, что у вашего стора отсутствует сид
(stable id), который необходим для корректной гидрации данных с сервера на клиент.
Чтобы исправить эту проблему вам нужно добавить этот сид
.
Сделать это вы можете несколькими способами:
-
Использовать babel или SWC плагин, который сделает все за вас
-
Или добавить
сид
в ручную, передав во второй аргументcreateStore
объект со свойствомsid
:const $store = createStore(0, {sid: "unique id",});
Более подробно про sid
, как это работает и зачем это нужно.
scopeBind: scope not found
Эта ошибка случается когда скоуп потерялся на каком-то из этапов выполнения и scopeBind
не может связать событие или эффект с нужным скоупом выполнения.
Эта ошибка могла быть вызвана:
- Вы используете режим работы ‘без скоупа’ и у вас их нет в приложении
- Ваши юниты были вызваны вне скоупа
Возможные решения:
-
Используйте
scopeBind
внутри эффектов:const event = createEvent();// ❌ - не вызывайте scopeBind внутри колбековconst effectFx = createEffect(() => {setTimeout(() => {scopeBind(event)();}, 1111);});// ✅ - используйте scopeBind внутри эффектаconst effectFx = createEffect(() => {const scopeEvent = scopeBind(event);setTimeout(() => {scopeEvent();}, 1111);}); -
Ваши юниты должны быть вызваны внутри скоупа:
- При работе с фреймворком используйте
useUnit
- Если у вас происходит вызов события или эффекта вне фреймворка, то используйте
allSettled
и передайте нужныйscope
в аргумент
- При работе с фреймворком используйте
Если того требует ваша реализация, а от ошибки нужно избавиться, то вы можете передать свойство safe:true
во второй аргумент метода.
const scopeEvent = scopeBind(event, { safe: true,});
call of derived event is not supported, use createEvent instead
Эта ошибка возникает, когда вы пытаетесь вызвать производное событие как функцию. Производные события создаются методами как .map()
, .filter()
, .filterMap()
, а также оператором sample
.
Чтобы исправить используйте событие созданное через createEvent
.
unit call from pure function is not supported, use operators like sample instead
Эта ошибка возникает, когда вы пытаетесь вызвать события или эффекты из чистых функций в Effector:
-
Вызов событий в методах событий
Когда вы пытаетесь вызвать одно событие внутри.map()
,.filter()
,.filterMap()
или.prepend()
другого события. -
Вызов событий в обработчиках сторов
При попытке вызвать событие в обработчике.on()
, внутри метода.map()
, или свойства конфигурацииupdateFilter()
стора. -
Вызов событий в функциях
sample
При вызове события в функцииfn
илиfilter
оператораsample
.
Как исправить: Вместо вызова событий в чистых функциях используйте декларативные операторы, например sample
.
Частые проблемы
sample.fn
не сужает тип, который приходит из sample.filter
Частая проблема с типизацией sample
происходит когда мы делаем проверку в filter
на что-то, но не получаем необходимый тип в fn
.
Мое состояние не изменилось
Скорее всего вы работаете со скоупами и в какой-то момент активный скоуп потерялся и ваш юнит выполнился в глобальной области.
Вы можете найти больше информации об этом тут.
Это происходит при передаче юнитов (события или эффекты) в колбэк внешних функций, таких как:
setTimeout
/setInterval
addEventListener
webSocket
и др.
Чтобы исправить эту проблему привяжите ваше событие или эффект к текущему скоупу при помощи scopeBind
:
const event = createEvent();
// ❌ - так у вас событие вызовется в глобальной области видимостиconst effectFx = createEffect(() => { setTimeout(() => { event(); }, 1000);});
// ✅ - так у вас будет работать как ожидаемоconst effectFx = createEffect(() => { const scopeEvent = scopeBind(event); setTimeout(() => { scopeEvent(); }, 1000);});
Использование юнитов без useUnit
Возможно вы используете события или эффекты во фреймворках без использования хука useUnit
, что может также повлиять на неправильную работу со скоупами.
Чтобы исправить это поведение передайте нужный юнит в useUnit
хук и используйте возвращаемое значение:
import { event } from "./model.js";
const Component = () => { return <button onClick={() => event()}></button>;};
import { event } from "./model.js";import { useUnit } from "effector-react";
const Component = () => { const onEvent = useUnit(event);
return <button onClick={() => onEvent()}></button>;};
Что такое потеря скоупа и почему это происходит
Не нашли ответ на свой вопрос ?
Если вы не нашли ответ на свой вопрос, то вы всегда можете задать сообществу:
Документация на английском языке - самая актуальная, поскольку её пишет и обновляет команда effector. Перевод документации на другие языки осуществляется сообществом по мере наличия сил и желания.
Помните, что переведенные статьи могут быть неактуальными, поэтому для получения наиболее точной и актуальной информации рекомендуем использовать оригинальную англоязычную версию документации.