Привет из магазина MiniRx
MiniRx Store - новый ребенок в блоке управления реактивным состоянием. MiniRx поможет вам управлять состоянием в крупном масштабе (с помощью Redux), но также предлагает простую форму управления состоянием: Магазины функций.
Давайте сделаем краткий обзор:
Глобальный
MiniRx Store - это глобальное решение для всего приложения для управления состоянием в приложениях JavaScript и TypeScript.
Реактивный
MiniRx работает на RxJS и предоставляет состояние как RxJS Observables. Observables испускаются при изменении их выбранного состояния.
Масштабируемый
MiniRx - это полноценное хранилище Redux: оно включает в себя действия, редукторы, мета-редукторы, запоминаемые селекторы и поддержку инструментов разработки redux.
Однако с MiniRx хранилища функций мы можем обойти шаблон Redux: сразу обновить состояние с помощью setState
.
MiniRx прекрасно масштабируется в соответствии с вашими требованиями к управлению состоянием:
- Упростите сложные задачи с помощью Redux API
- Упростите простые вещи с помощью Feature Store API
Быстрые ссылки
- 🤓 Узнайте больше о MiniRx на сайте Документов
- ⭐ MiniRx на GitHub
- 🚀 Посмотрите в действии на StackBlitz
ДНК MiniRx
NgRx
MiniRx вдохновлен NgRx, который является хорошо известным реактивным хранилищем Redux в мире Angular. На первый взгляд MiniRx и NgRx похожи, но есть и важные различия.
Что общего у NgRx и MiniRx?
- Их имена звучат похоже: попробуйте произнести их вслух;)
- На платформе RxJS
- Оба реализуют шаблон Redux.
- Состояние и действия отображаются как RxJS Observable.
Какие основные отличия?
- MiniRx не зависит от Angular и не зависит от платформы
- MiniRx имеет магазины функций для управления состоянием функций без шаблона Redux.
- MiniRx более легкий и, по общему признанию, не охватывает все безумные варианты использования управления состоянием.
И именно эти различия объясняют название «MiniRx».
Почему MiniRx
NgRx и шаблон Redux хорошо подходят для управления состоянием в большом масштабе. Но почти каждое приложение также содержит функции, требующие лишь простой формы управления состоянием. Тогда шаблон Redux с его действиями и редюсерами быстро становится излишним. Было бы здорово иметь решение для управления состоянием, которое выглядит и по ощущениям очень похоже на NgRx, но также должно поддерживать простое управление состоянием: Масштабируемое управление состоянием. Пришло время создать MiniRx Store:
Обход шаблона Redux с помощью магазинов функций
MiniRx использует шаблон Redux, чтобы сделать управление состоянием явным и предсказуемым. Шаблон Redux очень мощный, но он имеет некоторый шаблонный код (в основном действия, редукторы, действия диспетчеризации). MiniRx позволяет нам обойти шаблон Redux для простых состояний функций: с помощью Магазинов функций мы можем управлять состоянием функции напрямую, без действий и редуктора (просто используйте setState
для обновления состояния функции) .
Государственное управление, которое масштабируется
Для простых функций мы можем использовать магазины функций. А магазины функций могут быть довольно мощными: вы можете использовать мемоизированные селекторы (если хотите), вы можете создавать эффекты для вызовов API (если хотите). MiniRx прекрасно масштабируется в соответствии с вашими потребностями.
И вы всегда можете вернуться к Redux API, если вам нужно управлять огромным и сложным состоянием.
Фреймворк агностик
NgRx - отличный реактивный магазин, но в настоящее время он работает только в Angular. Существуют также другие фронтенд-фреймворки, такие как Svelte, которые поддерживают реактивность. Было бы здорово сделать в Svelte управление состоянием в стиле NgRx!
С MiniRx вы можете использовать любую структуру, которую захотите: вы можете создать независимый от платформы уровень управления состоянием для Angular сегодня и переместить его в Svelte (или любую другую структуру внешнего интерфейса) завтра.
Ключевые концепции MiniRx
- Хранилище - это единый объект, который хранит глобальное состояние приложения. Это «единственный источник истины»
- Состояние имеет плоскую иерархию и разделено на «состояния функций» (также называемые «срезами» в мире Redux).
- Для каждого «состояния функции» мы можем решить использовать Redux API с действиями и редуктором или API магазина функций с
setState
- Состояние отображается как RxJS Observable (Хранилище предоставляет глобальное состояние, а Хранилище функций - конкретное состояние функции).
- Состояние только для чтения (неизменяемое) и может быть изменено только путем отправки действий (Redux API) или с помощью
setState
(Feature Store API).
Это было долгое вступление! Давайте углубимся в код, чтобы увидеть MiniRx в действии ...
Базовое руководство
Магазин (Redux API)
MiniRx поддерживает классический Redux API с регистрацией редукторов и отправкой действий.
Наблюдаемое состояние можно выбрать с помощью мемоизированных селекторов .
import { Action, Store, configureStore, createFeatureSelector, createSelector } from "mini-rx-store"; import { Observable } from "rxjs"; // 1.) State interface interface CounterState { count: number; } // 2.) Initial state const counterInitialState: CounterState = { count: 1 }; // 3.) Reducer function counterReducer( state: CounterState = counterInitialState, action: Action ): CounterState { switch (action.type) { case "inc": return { ...state, count: state.count + 1 }; default: return state; } } // 4.) Get hold of the store instance and register root reducers const store: Store = configureStore({ reducers: { counter: counterReducer } }); // 5.) Create memoized selectors const getCounterFeatureState = createFeatureSelector<CounterState>("counter"); const getCount = createSelector( getCounterFeatureState, state => state.count ); // 6.) Select state as RxJS Observable const count$: Observable<number> = store.select(getCount); count$.subscribe(count => console.log("count:", count)); // 7.) Dispatch an action store.dispatch({ type: "inc" }); // OUTPUT: count: 1 // OUTPUT: count: 2
API магазина функций
Хранилища функций позволяют нам управлять состоянием функций без действий и редукторов.
API магазина функций оптимизирован для выбора и обновления состояния функции напрямую с использованием минимум шаблонов.
import { FeatureStore } from "mini-rx-store"; import { Observable } from "rxjs"; // 1.) State interface interface CounterState { counter: number; } // 2.) Initial state const counterInitialState: CounterState = { counter: 11 }; export class CounterFeatureStore extends FeatureStore<CounterState> { // Select state as RxJS Observable counter$: Observable<number> = this.select(state => state.counter); constructor() { super("counterFs", counterInitialState) } // Update state with `setState` inc() { this.setState(state => ({...state, counter: state.counter + 1})) } }
Используйте хранилище функций counterFs следующим образом:
import { CounterFeatureStore } from "./counter-feature-store"; const counterFs = new CounterFeatureStore(); counterFs.counter$.subscribe(count => console.log("count:", count)); counterFs.inc(); // OUTPUT: count: 11 // OUTPUT: count: 12
Состояние магазина функций становится частью глобального состояния
Каждый новый магазин функций будет отображаться в глобальном состоянии с соответствующим ключом функции (например, «counterFs»):
store.select(state => state).subscribe(console.log);
//OUTPUT: {"counter":{"count":2},"counterFs":{"counter":12}}
Примечания
Демо
🚀 Увидеть MiniRx Store в действии на StackBlitz
В демонстрации используются как Redux API, так и магазины функций:
- Todos: Магазин функций
- Продукты и корзина: Redux
- Пользователь: Магазин функций
Документация
🤓 Ознакомьтесь с документацией для получения полного API MiniRx.
Покажите свою поддержку
Если вам нравится MiniRx: поставьте на GitHub
использованная литература
Эти проекты, статьи и курсы помогли и вдохновили меня на создание MiniRx:
- NgRx
- Акита
- Наблюдаемый магазин
- Наблюдаемый магазин RxJS
- Магазин Джульетты
- Базовое государственное управление с наблюдаемой службой
- Redux с нуля с помощью Angular и RxJS
- Как я написал NgRx Store в 63 строчках кода
- NGRX VS. NGXS VS. AKITA VS. RXJS: БОРЬБА!
- Pluralsight: Angular NgRx: начало работы
- Pluralsight: RxJS в Angular: Реактивная разработка
- Pluralsight: RxJS: начало работы
Первоначально опубликовано на https://dev.to 26 февраля 2021 г.