Маленькая и незаметная библиотека управления состоянием для приложений на React и Preact
Текущий размер файла statty/dist/statty.umd.min.js
составляет:
Большинство времени я вижу коллег, начинающих проекты на React с установкой Redux + целого набора middleware и enhancers хранилища по умолчанию, вне зависимости от природы проекта.
Хотя Redux действительно отличная вещь, она не всегда нужна и может замедлить процесс обучения новых разработчиков, особенно если они новички в экосистеме React (часто видел, как коллеги застревали на несколько часов, пытаясь понять, какой правильный способ отправить простую форму).
React уже имеет встроенную систему управления состоянием, setState()
. Локальное состояние компонента обычно вполне достаточно в большинстве случаев.В реальных приложениях мы часто сталкиваемся с состоянием приложения, и иногда становится утомительно передавать его через всю деревню компонентов вместе с коллбэками для обновления этого состояния через props.
statty
предназначен для управления общим состоянием приложения и можно рассматривать как упрощённую версию Redux.
Он безопасно использует контекст для предоставления состояния приложения дочерним компонентам, а также функции для его обновления по мере необходимости. Функция обновления работает как dispatch
в Redux, но вместо действия принимает функцию-обновитель (updater
), которая возвращает новое состояние.
Таким образом легко писать тестируемые обновители и организовывать их так, как вам нравится, без необходимости писать лишний код.
Этот проект использует Node и NPM. Изучите их, если они ещё не установлены локально.
$ npm i statty
Затем с помощью модульного бандлера, такого как Rollup или Webpack, используйте его аналогично любому другому модулю:
// использование ES6 модулей
import statty from 'statty'
```// использование модулей CommonJS
var statty = require('statty')
Сборка UMD также доступна на Unpkg:
<script src="https://unpkg.com/statty/dist/statty.umd.js"></script>
Вы можете найти библиотеку на window.statty
.
// https://codesandbox.io/s/rzpxx0w34
import React from 'react'
import { render } from 'react-dom'
import { Provider, State } from 'statty'
import inspect from 'statty/inspect'
// селектор — это функция, которая возвращает часть состояния
// если не указано, то по умолчанию используется f => f
const selector = state => ({ count: state.count })
// обновители
// обновители ДОЛЖНЫ быть чистыми и возвращать полное новое состояние,
// как редукторы в Redux
const onDecrement = state =>
Object.assign({}, state, { count: state.count - 1 })
const onIncrement = state =>
Object.assign({}, state, { count: state.count + 1 })
// Счетчик использует компонент <State>, чтобы получить доступ к состоянию
// и использовать функцию обновления для выполнения мутаций состояния
const Counter = () => (
<State
select={selector}
render={({ count }, update) => (
<div>
<span>Нажатий: {count} раз(а)</span>
<button onClick={() => update(onIncrement)}>+</button>{' '}
<button onClick={() => update(onDecrement)}>-</button>{' '}
</div>
)}
/>
)
// начальное состояние
const initialState = {
count: 0
}
// Компонент <Provider>
должен располагаться в вершине вашего приложения. Он принимает начальное состояние и функцию inspect
, полезную для логирования изменений состояния во время разработки
// (проверьте ваши инструменты разработчика, чтобы увидеть это в действии)
const App = () => (
)
render(, document.getElementById('root'))
Компонент `<Provider>` используется для передачи состояния через контекст.
Компонент `<State>` принимает 2 пропса:
* `select` — это функция, которая принимает полное состояние и возвращает только ту его часть, которую потребуют дочерние компоненты,
* `render` — это [render prop](https://cdb.reacttraining.com/use-a-render-prop-50de598f11ce), который принимает отфильтрованное состояние и функцию `обновления`, предоставляющую пользователю полный контроль над тем, что будет отображено на основе пропсов и состояния.
Обновление состояния происходит с помощью специальных функций `обновления`, которые принимают старое состояние как аргумент и возвращают новое состояние, запуская перерender.
Функция обновления может вернуть срез изменённой части состояния или полностью новое состояние. В первом случае новый срез будет поверхностно объединён с старым состоянием.
## API
### `<Provider>`
Делает доступным состояние для дочерних компонентов `<State>`
#### пропсы
##### `state`
> `объект` | обязательный
Начальное состояние
##### `inspect`
> `функция(oldState: объект, newState: объект, updaterFn: функция)`
Используйте проп `inspect` во время разработки для отслеживания изменений состояния.
`statty` поставляется с дефолтным логгером, вдохновлённым redux-logger.
```jsx
<Provider
state={{count: 0}}
inspect={require('statty/inspect')}
/>
```
### `<State>`
Связывает дочерние компоненты со изменениями состояния и предоставляет им функцию `обновления`.
```#### Пропсы
##### `select`
> `функция(state: объект) | по умолчанию s => s | возвращает объект`
Выбирает срез состояния, необходимый для работы дочерних компонентов.
##### `render`
> `функция(state: объект, update: функция)` | обязательный
Render prop, который принимает состояние, возвращаемое селектором, и функцию `update`.
## Примеры
Примеры существуют на [codesandbox.io](https://codesandbox.io/search?refinementList%5Btags%5D%5B0%5D=statty%3Aexample&page=bk=1):
- [Подсчёт значений](https://codesandbox.io/s/rzpxx0w34)
- [Пример с использованием Preact без совместимости Preact (codepen)](https://codepen.io/vesparny/pen/gGgyVN)
- [Подсчёт значений с использованием редьюсеров](https://codesandbox.io/s/jp9zj98l5w)
- [Подсчёт значений с асинхронными взаимодействиями](https://codesandbox.io/s/kxkp47o597)
- [Поиск информации в Википедии с использованием RxJS и Ramda](https://codesandbox.io/s/7wx3v8jqqq)
- [Поиск информации в Википедии + интеграция с Downshift](https://codesandbox.io/s/pymj32z5kj)
- [Пример дерева](https://codesandbox.io/s/3y146z2qop) (показывает, как добиться хорошей производительности при работе с вложенными подписками).
Если вы хотите добавить пример, следуйте этим шагам:
1) Создайте форк этого [codesandbox](https://codesandbox.io/s/rzpxx0w34)
2) Убедитесь, что ваша версия (в разделе зависимостей) является последней доступной версией
3) Обновите заголовок и описание
4) Обновите код для вашего примера (добавьте какое-либо объяснение, чтобы описать его содержание)
5) Добавьте тэг: `statty:example`## Вдохновение
* [Пост Майкла Джексона](https://github.com/mjackson) о [рендер-псах](https://cdb.reacttraining.com/use-a-render-prop-50de598f11ce)
* [refunk](https://github.com/jxnblk/refunk/)
## Тесты
```sh
$ npm run test
```
## ЛИЦЕНЗИЯ
[Лицензия MIT](LICENSE.md) © [Александро Арнодо](https://alessandro.arnodo.net/)
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )