Как стать автором
Обновить

Комментарии 31

Боже, хотите простоты используйте mobx...

Я считаю, что statirjs будет проще осваивать для людей, которые используют redux-like state manager'ы. Словарь терминов и их реализация переиспользуется.
Redux — сложная и перегруженная лишним система, вы лишь немного ее упростили. Пайпы, диспатчи, билдеры, возвращение целого объекта стора в каждом экшене в иммутабельном формате… Это не просто и смысл создания подобного очень туманен. Без проблем готов обстоятельно сравнить с observable-стором, в котором все решения будут выглядеть намного чище и проще.
Скажите пожалуйста, что может быть сложнее чем это??? Сразу же пример с локальным стейтом компонента и с глобальным стейтом приложения. Да ничего проще быть не может в принципе.
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
Только mobx + binding к react + mobx-state-tree ~ 50Kb gzip кода, а redux + react-redux ~ 8Kb gzip кода.

Ну и в конце, автор предложил достаточно крутое решение, чтобы избавить redux от бойлерплейта, а вы снова про mobx. Зачем?)
Mobx в gzip весит 15кб. А обвязка к реакту — 1.8кб. Если версия реакта позволяет использовать хуки, то можно использовать официальный mobx-react-lite вместо mobx-react.

автор предложил достаточно крутое решение, чтобы избавить redux от бойлерплейта

Проблема в том, что тут чуть ли не каждый второй пост про стейт-менеджер это презентация своего велосипеда или обёртки над Redux:
Организация reducer'а через стандартный класс
Redux-symbiote — пишем действия и редьюсеры почти без боли
Redux — пересмотр логики reducer'a и actions
Оверинжинирг 80 уровня или редьсюеры: путь от switch-case до классов
Люди решают проблемы, которые уже давно решены другими инструментами, проверенными временем. Поэтому появляются люди, рассказывающие об этих инструментах.
bundlephobia.com/result?p=mobx@5.15.4 ~15.4Kb
bundlephobia.com/result?p=mobx-react@6.2.2 ~5KB
bundlephobia.com/result?p=mobx-state-tree@3.16.0 ~ 20Kb
И это только тот код, который позволит с mobx как-то удобно работать.

В том то и прелесть, что можно как угодно организовать. Есть у redux проблема с boilerplate — есть решения. Сама концепция единого стора же простая.
Общий размер Mobx + mobx-react-lite на современном React — 15.4 + 1.8кб, а не 50. Ссылки на bundlephobia в посте выше. MST даёт дополнительные инструменты вроде рантайм проверки типов, нормализации из коробки и time travel, что вряд ли нужно в простом приложении.
Я одной вещи не понимаю, зачем под каждой статьей про redux писать про mobx? Еще и с эмоциями типа «Боже....». Вы правда думаете, что есть еще те, кто не знает про mobx?
Потому что нелепо в 2020 году до сих пор использовать redux-like дичь, или писать не реактивные стейт менеджеры тем более иммутабильные. Более того это нелепо было уже в 2016 году, просто не так ярко выражено.
Знают, но большинство новых проектов стартуют на Redux, судя по тем собеседованиям, на которые хожу. Почему?
В свое время это был хайп, который здравомыслящие люди обходили стороной ввиду больших сложностей применения на практике, но пора бы уже подобным концептам уйти на покой и быть признанными нежизнеспособными. Однако разработчики продолжают по каким-то причинам мусолить эту тему, а Абрамов вместо того, чтобы признать, что создал стремную систему, еще и в реакт-хуки запихивает имплементацию. Как тут без эмоций?

Да, действительно. Есть такие. К сожалению, мой опыт относительно редакса негативный: приходилось работать с кодом, где редакс исковеркан и использован неправильно.
Redux-toolkit исправляет задачу. А вместе с normalizr мы приходим к почти mst.
Теперь в redux'е есть immer.js, от создателей mobx.


Сейчас, написав и участвовав в написании около 10 приложений, понимаю, что проще использовать mobx + mst. Чем Redux, чем стейт-менеджмент на хуках, и даже, чем redux-toolkit.


А рассматриваемая библиотека напоминает slice из redux-toolkit. Только у нее наверняка хуже документация и меньше ответов на stackoverflow. Не весь же код пишут сеньоры

Используя mst вы убиваете все приемущества и кайф от mobx'a. Зачем?????
Представим что нужно декрементировать значение. С 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 класса и потом дергает их нужные методы и свойства.
По сути просто не нужно обращаться к соседним сторам в constructor, то есть сначала создается весь стор целиком, а потом вызываются методы. Так не будет никаких undefined, и setTimeout не пригодится) Так что тоже не считаю это проблемой
Я же написал
Если вы планируете что сторы будут зависить на прямую друг от друга и в конструкторе вызывать свойства и методы друг друга, то это не правильный дизайн

А потом
но если все же такая необходимость нужна
Ну да, я лишь дополнил варианты в случае, когда «необходимость нужна», противоречий нет)
В редаксе действительно 1 стор, но состоит он из стольких «подсторов» с редюсерами, сколько нужно приложению:

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 внутри самих форм.

Хочу обратить ваше внимание, что с MobX вы просто изменяете свойства объекта/класса и всё работает.
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 в целом). Но в целом любопытный проект.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории