Комментарии 31
Боже, хотите простоты используйте mobx...
class LocalState {
@observable counter = 0;
@observable title = 'title';
incr = () => {
this.counter++;
}
handleTitleChange = (e) => {
this.title = e.target.value;
}
}
class GlobalState {
@observable counter = 0;
@observable title = 'global title';
incr = () => {
this.counter++;
}
handleTitleChange = (e) => {
this.title = e.target.value;
}
}
const globalState = new GlobalState();
export const App = observer(() => {
const [ state ] = useState(() => new LocalState());
return (
<div>
<h1>{state.title}</h1>
<h2>{globalState.title}</h2>
<div>Local Counter: {state.counter}</div>
<div>Global Counter: {globalState.counter}</div>
<div>
<button onClick={state.incr}>Local incr</button>
<button onClick={globalState.incr}>Global incr</button>
</div>
<div>
<input value={state.title} onChange={state.handleTitleChange} />
<input value={globalState.title} onChange={globalState.handleTitleChange} />
</div>
</div>
);
});
Вот — codesandbox.io/s/interesting-snyder-v8k4o?file=/src/App.tsx
Ну и в конце, автор предложил достаточно крутое решение, чтобы избавить redux от бойлерплейта, а вы снова про mobx. Зачем?)
автор предложил достаточно крутое решение, чтобы избавить redux от бойлерплейта
Проблема в том, что тут чуть ли не каждый второй пост про стейт-менеджер это презентация своего велосипеда или обёртки над Redux:
— Организация reducer'а через стандартный класс
— Redux-symbiote — пишем действия и редьюсеры почти без боли
— Redux — пересмотр логики reducer'a и actions
— Оверинжинирг 80 уровня или редьсюеры: путь от switch-case до классов
Люди решают проблемы, которые уже давно решены другими инструментами, проверенными временем. Поэтому появляются люди, рассказывающие об этих инструментах.
bundlephobia.com/result?p=mobx-react@6.2.2 ~5KB
bundlephobia.com/result?p=mobx-state-tree@3.16.0 ~ 20Kb
И это только тот код, который позволит с mobx как-то удобно работать.
В том то и прелесть, что можно как угодно организовать. Есть у redux проблема с boilerplate — есть решения. Сама концепция единого стора же простая.
В свое время это был хайп, который здравомыслящие люди обходили стороной ввиду больших сложностей применения на практике, но пора бы уже подобным концептам уйти на покой и быть признанными нежизнеспособными. Однако разработчики продолжают по каким-то причинам мусолить эту тему, а Абрамов вместо того, чтобы признать, что создал стремную систему, еще и в реакт-хуки запихивает имплементацию. Как тут без эмоций?
Да, действительно. Есть такие. К сожалению, мой опыт относительно редакса негативный: приходилось работать с кодом, где редакс исковеркан и использован неправильно.
Redux-toolkit исправляет задачу. А вместе с normalizr
мы приходим к почти mst.
Теперь в redux'е есть immer.js, от создателей mobx.
Сейчас, написав и участвовав в написании около 10 приложений, понимаю, что проще использовать mobx + mst. Чем Redux, чем стейт-менеджмент на хуках, и даже, чем redux-toolkit.
А рассматриваемая библиотека напоминает slice из redux-toolkit. Только у нее наверняка хуже документация и меньше ответов на stackoverflow. Не весь же код пишут сеньоры
Представим что нужно декрементировать значение. С statirjs это будет быстро и просто:Быстро и просто это так:
+ decrement: (state) => ({ count: state.count - 1 })
state.count--
Аналогично для dispatch'а. Просто — это когда counter.increment(), а не хуки на все экшны:
const increment = useDispatch((dispatch) => dispatch.counter.increment);
1. желание иметь простой redux как rematch;
Используйте обычный react state.
Не буду писать про mobx, но у меня такое ощущение, что через пару лет, люди поймут, что это очень большой over engineering и наконец начнут использовать просто state и вспомогательные функции для преобразования, что то вроде rxjs.
Не буду писать про mobx, но у меня такое ощущение, что через пару лет, люди поймут, что это очень большой over engineering и наконец начнут использовать просто state и вспомогательные функции для преобразования, что то вроде rxjs.
MobX оверинжинеринг? Это не более чем использование возможностей языка для максимального удобства в разработке. А пользоваться им настолько просто, что даже тапочек сложнее.
Вот пожалуйста — codesandbox.io/s/interesting-snyder-v8k4o?file=/src/App.tsx
Проще просто не может быть, изменяешь переменную и там где надо вызываются реакции на эти изменения, вот и всё.
Не в защиту redux like решений, но все же в mobx тоже свои особенности, основная это концепция мультисторов, что приводит к необходимости управления жизненным циклом этих сторов, и организации их взаимодействия друг с другом. Чего естественно нет в решениях с одним стором типа redux.
Я не понял что вы называете "многочисленные одноуровневые сторы", но насколько я помню идея редакса в том что там один стор который обязательно синхронно меняется, и на него подписаны компоненты.
В mobx же для сторов используются классы для того чтобы сделать их поля observable, так как это классы, то для их использования необходимо создавать инстансы сторов, как только вы начинаете работать с классами и инстансами у вас возникает вопрос правильной последовательности создания этих инстансов и всякие dependency injection и тп штуки.
то для их использования необходимо создавать инстансы сторов, как только вы начинаете работать с классами и инстансами у вас возникает вопрос правильной последовательности создания этих инстансов и всякие dependency injection и тп штуки.
1) Накой собвственно вам «всякие dependency injection и тп штуки»?? Они как бы нафиг не нужны.
2) Причем тут «правильная» последовательность? Если вы планируете что сторы будут зависить на прямую друг от друга и в конструкторе вызывать свойства и методы друг друга, то это не правильный дизайн, но если все же такая необходимость нужна, это решается разными методами, например в конструкторе класса которые перекрестно используют друг друга дергать методы только после setTimeout, чтобы они оба на момент дергаться были инициализированы и не получилось так, что кто-то из них пока что-то undefined, или же создается промежуточный класс или функция, которая импортирует эти 2 класса и потом дергает их нужные методы и свойства.
Если вы планируете что сторы будут зависить на прямую друг от друга и в конструкторе вызывать свойства и методы друг друга, то это не правильный дизайн
А потом
но если все же такая необходимость нужна
import { combineReducers } from "redux";
import store1 from "./store1";
import store2 from "./store2";
// + 100500 других сторов
export default combineReducers({
store1,
store2,
});
В MobX тоже можно комбинировать «подсторы»:
import { Store1 } from './Store1 ';
import { Store2 } from './Store2 ';
export class StoreRoot {
constructor() {
this.store1 = new Store1();
this.store2 = new Store2();
}
}
То есть по способу компоновки сторов очень похоже. Вы, наверное, имеете в виду ситуацию, когда Store1 должен обратиться к Store2? Это решается несложно. А в редаксе другая схема работы — в нем сторы вообще не могут общаться, они просто содержат данные, а экшены могут обращаться с помощью глобальных констант к любому стору. Можно сделать такую же схему и на MobX, он никак не ограничивает возможности.
Хочу обратить ваше внимание, что ststirjs позволяет взаимодействовать между formes (считай подсторомами) через dispatch внутри самих форм.
this.isFetching = true;
const response = await apiRequest(`GET /items`);
this.items = response.items;
this.isFetching = false;
И всё! Я надеюсь вы понимаете что ваше решения мягко говоря гораздо более громоздкое, неудобное, не использует возможности языка и т.д и т.п.
Вы как будто специально игнорируете то, что в JS уже очень давно есть Proxy и Getters/Setters (если нужна поддержка совсем древних браузеров).
Игнорировать их и не пользоваться этим благом просто абсурдно и смешно, тем более в 2020 году, хотя этим уже много лет активно пользуются, но мазохисты конечно же об этом либо не знают, либо отрицают.
Мы все делаем вид, что unstated-next не существует, я правильно понимаю?
Интересное решение, но statirjs предполагает независимое от фреймворков ядро с коннекторами, а unstated-next нет. Преимуществом может являться нативность unstated-next относительно react, но это повышает связанность с ним же (насколько сильно поменяется react api, настолько же и весь unstated-next в целом). Но в целом любопытный проект.
Простой state manager для простой работы