Search
Write a publication
Pull to refresh

Comments 35

Хотелось бы увидит как оно будет использоваться внутри react

Никак, учитывая, что

  1. Computed всегда будут вычисляться от атомов или коллекций, даже если в коде вы укажете только Computed. На этой библиотеке Excel не построить, пока что.

  2. Нет глубокого отслеживания изменения объектов. Если значение атома - объект, то не забывайте прямо указывать присваивание свойству value нового значения.

А что вы собрались оборачивать? Virtual DOM что ли? Вообще, манипуляции с DOM (обновление) должны быть внутри реакции, неважно какую библиотеку рендеринга вы используете в работе.

Ну действительно, при использовании других стейт менеджеров в реакте же оборачивают vdom

Во-первых, явно нескоро.

Во-вторых, потом опять пойдет волна библиотек, которые будут их оборачивать. Например, будут писать обновление данных одним пакетом и отложенные реакции. И будут думать, как выстраивать порядок выполнения реакций (эффектов).

Никто сейчас в здравом уме не оборачивает нативные Промисы или методы коллекций для массивов.

Более того, многие библиотеки стали выкидывать после перехода нативных методов просто в Stage3, потому что разницы по производительности между полифилом и рандомной библиотекой нет, а у полифила хотя бы не находят каждый год фатального недостатка в API.

Промисы просты как валенок
Если посмотреть на fine-grained Reactivity API Vue, то просто сигналов однозначно мало
Реактивность примитивов, объектов, массивов, глубокая и shallow, scopes

Честно говоря, не понял причем тут обёртка методов и промисов. Оборачивают объекты и строят абстракции над объектами для того, чтобы добавлять функционал.

А что касается тех сигналов, то там пока Stage1. Говорить рано ещё о них.

Непонятно зачем минусуют люди. Исходники есть, можно все глянуть. Комментарии в исходнике вполне себе нормальные. Может из-за позиционирования?

Мне вот иногда нужен простой стейт менеджер на бэке, дак днем с огнем что то простое не сыщешь.

Единственное что бросается в глаза - очень длинные названия методов и многословность.

Имхо сравнивают с mobx и понимают что mobx лучше.

Пока в комментариях видел только один пример с MobX, и то, всю красоту работы MobX спрятали во внешнюю функцию observer - адаптер для реакта.

А зачем стейт менеджер на бэке, можно узнать?
Задачи какого типа?

Мне нужно было для реализации приложения которое работает в режиме "онлайн" по websocket.

Если честно, то это вообще полная фигня. Просто посмотрите на MobX, он на 3 головы лучше и удобнее. Там все подписки/отписки автоматические, как и должно быть. Из "оверхеда" по коду только makeAutoObservable(this); в конструкторе классов с состоянием и observer() для заворачивая компонентов. Всё.
Просто посмотрите https://stackblitz.com/edit/vitejs-vite-y2qj7g?file=src%2FApp.tsx&terminal=dev

В своем примере вы показали, как MobX прибит к реакту.

Он не прибит к реакту. Посмотрите примеры из самого mobx.

Я знаю эту библиотеку. Но то, что указано выше - это биндинг данных к JSX реакта. Читайте как демонстрация работы внешней функции observer, а не то как библиотека работает с данными.

Если бы пример был более нативный, то тогда было бы интереснее сравнить.

В публикации речь же идет о ядре. А адаптеры для фреймворков - все-таки отдельные проекты. Для реакта потом напишу. Там тоже будет одна функция.

Т.е. либа агностик, но для реакта нет реализации. Понятно. А в чем принципиальное отличие от Zustand если вам MobX не угодил?

Разъясните противопоставление "агностик" и "для реакта нет реализации".

  1. Вы упростили пример - нету кейса когда необходимо делать реакцию на изменения 2 свойств. судить о читабельности - рано кмк.

  2. Необходимо явно подписываться на изменения свойств - при рефакторинге, изменении требований, etc - легко забыть подписаться на нужное свойство/отписаться от ненужного. Да и не хочется этим заниматься.

  3. В коде используются магические константы - при рефакторинге/наборе можно перепутать.

Выделил отдельно код по кейсу с двумя переменными:

  1. mobx

autorun(() => {
  counter1div.innerHTML = `counter 1: ${state.counter1}`;
  counter2div.innerHTML = `counter 2: ${state.counter2}`;
});
  1. Ваше

counter1div.innerHTML = `counter 1: ${state.counter1}`;
counter2div.innerHTML = `counter 2: ${state.counter2}`;

const counter1 = store.getAtom('counter1');
const counter2 = store.getAtom('counter2');

store.onChangeAny([counter1, counter2], () => {
  counter1div.innerHTML = `counter 1: ${state.counter1}`;
  counter2div.innerHTML = `counter 2: ${state.counter2}`;
});

Вы правда считаете, что распухание кода в 2 раза, копипаста и boilerplate ведет к увеличение читабельности кода?

Давайте я вам помогу лучше.Так будет нагляднее.

Bundle size

  1. mobx (60.8 kB MINIFIED, 17.1 kB MINIFIED + GZIPPED)

  2. Supercat Store (11.5 kB MINIFIED, 3.6 MINIFIED + GZIPPED)

Autorun

  1. mobx

autorun(() => {
  counter1div.innerHTML = `counter 1: ${state.counter1}`;
  counter2div.innerHTML = `counter 2: ${state.counter2}`;
});
  1. Supercat Store

    Решение через строковый API

function foo() {
    counter1div.innerHTML = `counter 1: ${state.counter1}`;
    counter2div.innerHTML = `counter 2: ${state.counter2}`;
}

foo();

store.onChangeAny(["counter1", "counter2"], foo);

Решение через реактивные переменные

function foo() {
    counter1div.innerHTML = `counter 1: ${state.counter1}`;
    counter2div.innerHTML = `counter 2: ${state.counter2}`;
}

foo();

const counter1 = store.getAtom('counter1');
const counter2 = store.getAtom('counter2');

store.onChangeAny([counter1, counter2], foo);

Reaction

  1. mobx

reaction(
  () => [state.counter3],
  () => {
    counter3div.innerHTML = `counter 3: ${state.counter3}`;
  }
);
  1. Supercat Store

    Решение через строковый API

store.subscribe("counter3", () => {
  counter3div.innerHTML = `counter 3: ${state.counter3}`;
});

Решение с помощью реактивных переменных

const counter3 = store.getAtom('counter3');

counter3.subscribe(() => {
  counter3div.innerHTML = `counter 3: ${state.counter3}`;
});

When

  1. mobx

(async () => {
  await when(() => state.counter1 >= 3);

  alert('Another cool thing is when');
})();
  1. Supercat Store (четко структуированный код)

С помощью реактивных переменных

const when = store.createComputed(() => {
  return state.counter1 >= 3;
});

when.subscribe(() => {
  alert('Another cool thing is when');
});

Как бы объяснить. Не все что меньше строк - лучше.

Посмотрев на код с использованием Supercat Store, программист, не знакомый с библиотекой, поймет что делает код. С ней легко начать работу даже новичку и потом контролировать что новичок написал.

По поводу использования реактивных переменных, очевидно, что работа с ними безопаснее работы с апи на строках. Цена удобства - 1 строка кода на каждую переменную. При этом объявление атома не является каким-то тяжким трудом. Библиотека типизирована. Редактор кода подскажет методы создания реактивных переменных и работы с ними. Реактивные переменные легко импортировать из других модулей, а также найти их референсы по всему проекту. Плюсов вагон и маленькая тележка.

Еще скажу, что архитектура, построенная с помощью явных подписок на конкретные реактивные переменные - это и есть ключ к написанию корректного кода, в нем невооруженным глазом виден принцип разделения ответственности.

И, самое главное, такой подход за счет атомарности и разделения ответственности дает возможность безопасно масштабировать код.

Давайте я вам помогу лучше.Так будет нагляднее.

дак и до этого было все видно. там остальные случаи слишком простые и на них не видно было суть.

Посмотрев на код с использованием Supercat Store, программист, не знакомый с библиотекой, поймет что делает код. С ней легко начать работу даже новичку и потом контролировать что новичок написал.

c mobX еще проще - т.к. там действий меньше. меньше действий => проще понять что происходит.

По поводу использования реактивных переменных, очевидно, что работа с ними безопаснее работы с апи на строках

в mobX работа идет на уровне свойств стора. помогает ide и компилятор, что еще 'более безопаснее'.

Редактор кода подскажет методы создания реактивных переменных и работы с ними.

И наверное подскажет то, что при вызове store.getAtom() передано неправильное имя свойства стора?

Еще скажу, что архитектура, построенная с помощью явных подписок на конкретные реактивные переменные - это и есть ключ к написанию корректного кода, в нем невооруженным глазом виден принцип разделения ответственности.

просто Ваша либа не умеет в автоматические подписки.

просто Ваша либа не умеет в автоматические подписки.

Все давно было предусмотрено. Все умеет. Добавил autorun, when, reaction.

// @ts-check
import { Store } from '@supercat1337/store';

class State {
  counter1 = 0;
  counter2 = 0;
  counter3 = 0;

  incr1 = () => {
    this.counter1++;
  };

  incr2 = () => {
    this.counter2++;
  };

  incr3 = () => {
    this.counter3++;
  };
}

const store = new Store();
const state = store.observeObject(new State());

const counter1div = document.createElement('div');
const counter2div = document.createElement('div');
const counter3div = document.createElement('div');

const btn1 = document.createElement('button');
btn1.innerText = 'inct 1';
btn1.addEventListener('click', state.incr1);

const btn2 = document.createElement('button');
btn2.innerText = 'inct 2';
btn2.addEventListener('click', () => {
  state.counter2++;
});

document.body.appendChild(counter1div);
document.body.appendChild(counter2div);
document.body.appendChild(counter3div);
document.body.appendChild(btn1);
document.body.appendChild(btn2);

(async () => {
  await store.when(() => state.counter1 >= 3);

  alert('Another cool thing is when');
})();

// Trigger when counter1 or counter2 changed
store.autorun(() => {
  counter1div.innerHTML = `counter 1: ${state.counter1}`;
  counter2div.innerHTML = `counter 2: ${state.counter2}`;
});

// Trigger when counter3 changed (another way)
store.reaction(
  () => [state.counter3],
  () => {
    counter3div.innerHTML = `counter 3: ${state.counter3}`;
  }
);

setInterval(state.incr3, 1000);

https://stackblitz.com/edit/vitejs-vite-lygwhz?file=main.js&terminal=dev

UFO landed and left these words here
UFO landed and left these words here

Я человек простой - вижу var в js коде, дальше не читаю...

Конечно, не надо! И когда в следующий раз увидите var, обязательно сообщите это читателям.

Sign up to leave a comment.

Articles