Работаю сейчас с zustand, который уже обогнал redux по загрузкам. Вот что говорят адепты zustand, сравнивая его с redux:
Миф 1: В Zustand можно создавать множество сторов вместо одного!
По факту и правда можно, но в доке Zustand советуют «single store». А если мол ваше приложение большое, можете разделить стор на слайсы.
В redux тоже single store, который можно разделить на слайсы. И в отличие от zustand, есть встроенное решение для динамической подгрузки слайсов, что позволяет делать код-сплиттинг и загружать только нужные слайсы.
Миф 2: В Zustand меньше бойлерплейта!
По факту и правда меньше, пока у тебя стор размером с "counter, increment, decrement". Как только тебе надо обновить поле где-то глубоко в дереве:
updateNestedParam: (value: string) => {
set((state) => ({
deep: {
...state.deep,
nested: {
...state.deep.nested,
obj: { ...state.deep.nested.obj, param: value }
}
}
}))
}В то время как в redux уже давно можно просто:
updateNestedParam: (state: MyState, value: string) => {
state.deep.nested.obj.param = value
}Чтобы решить эту проблему документация zustand советует нам
immer. На этой библиотеке как раз работает redux, просто она уже встроена. А с zustand нужно писать всё вручную. Есть ещё опция прикрутить immer middleware, чтобы получилось ну-вот-уже-почти-как-в-redux, только вместо одной функции надо две писать:updateNestedParam: (value: string) => {
set(state => {
state.deep.nested.obj.param = value
})
}Миф 3: Ура, не нужно использовать Provider!
И правда не нужно. А это точно преимущество? Чтобы написать тесты на компонент, использующий redux, нужен враппер с preloadedState. В Zustand советуют мокать (!) методы самого zustand, чтобы добавить в каждый стор метод очистки, и вызывать это в afterEach — а что если мне в тесте нужен не initialState, а какой-то уже наполненный. Опять всё руками? ЛИБО, внимание, использовать Context API, чтобы предоставить компонентам конкретный инстанс стора. В чём разница с Redux Provider?
Миф 4: Zustand лучше перфоманс!
И показывают бенчмарки на батчевую запись в стор, где в redux используется immer, а в zustand его не добавляют, и пишут тот самый бойлерплейт из мифа №2. Мы точно сравниваем полноценные решения на реальном юз-кейсе? Или подгоняем задачу под ответ?
Я повидал разные проекты. Вопрос производительности библиотек встаёт на масштабах главной страницы Яндекса, где сам код приложения уже оптимизирован донельзя. Проекты поменьше, даже если там сложные графики с 5-летними данными с дневной гранулярностью (зачем), или формы с 200 селектами (зачем), тормозят не из-за стейт-менеджера, а из-за того, как написано само приложение.
Миф 4.1: В Zustand селекторы более гранулярные, именно это влияет на перфоманс!
В zustand можно так:
useMyStore(state => state.very.deep.object.prop)
Но в redux можно точно также:
useSelector(state => state.very.deep.object.prop)
В чём разница? Получили ли мы что-то новое в Zustand, или авторы просто строят очередной Redux?