➪ Легко изучается
➪ Маленький и быстрый
➪ Для приложений любого масштаба
Экономия времени на кодирование!
Минимальная, хорошо структурированная и гибкая кодовая база экономит много времени разработчиков на поддержку и развитие ваших React-приложений.
Как это работает
Обычно, когда вы только начинаете React-проект или имеете очень маленький проект, ваша кодовая база коротка, понятна и проста, вы можете легко нагуглить примеры распространенных проблем.
Но по мере написания бизнес-логики вашего приложения код становится все больше и больше, и разобраться в обилии файлов, трюков и кусков кода становится все сложнее.
Вы должны четко понимать, где место для вашей логики, и как вы можете писать столько кода, сколько хотите, не снижая при этом уровень обслуживания приложения.
- Как сделать простое React-приложение, которое можно легко нарастить до большого приложения по требованию бизнеса
- Как организовать чистый код с минимальными состояниями и удобно разделенной логикой
- Как ускорить работу приложения и сократить количество «котельного» кода
Мой ответ — Ремини 😍
Начните
Сначала у вас есть состояние 😊.
const $user = box({ email: 'a@x.com' })
const $enabled = box(true)
const $counter = box(42)
const $books = box([ 'The Little Prince', 'Alice in Wonderland' ])
Во вторых, привяжите состояние к компоненту React!
const Books = () => {
const books = useBox($books)
return <ul>
{books.map(book => <li>{book}</li>)}
</ul>
}
На третьем, обновляем состояние 👍
const BookForm = () => {
const [name, setName] = React.useState('')
return <p>
<input
value={name}
onChange={event => setName(event.target.value)}
/>
<button
onClick={() => update($books, books => [...books, name])}
>Add</button>
</p>
}
В четвертых, поделитесь своей логикой 😉
// ./books.shared.js
export const $books = box([])
export const $loading = box(false)
export const load = async () => {
write($loading, true)
const response = await fetch('https://example.com/api/books')
const books = await response.json()
write($books, books)
write($loading, false)
}
const BooksLoad = () => {
const loading = useBox($loading)
return <p>
{loading ? 'Loading...' : (
<button onClick={load}>Load</button>
)}
</p>
}
Несколько магазинов против одного магазина
Одним из проявлений является архитектура с несколькими магазинами. Основная причина — декомпозиция независимых модулей. Для гибкого роста необходимо разделять код. Ваше приложение должно быть построено на основе разделенных модулей. Каждый модуль содержит некоторые данные и логику.
Это очень хорошее архитектурное решение, потому что вы можете разрабатывать и тестировать каждый модуль отдельно. Вы можете легко повторно использовать модули между проектами. И когда вы используете ленивую загрузку для некоторых частей вашего приложения, у вас никогда не будет проблем с этим, просто импортируйте его и используйте. Все должно быть просто!
Ок. Первое — это раздельная декомпозиция модулей, а что дальше?
Если каждый модуль имеет собственное состояние и логику, то очень удобно использовать отдельные хранилища для управления потоком данных.
В этот момент самое время сделать постулат: каждое хранилище должно быть простым, и никогда не рекомендуется делать глубоко вложенные состояния. Лучший способ — следовать принципу KISS.
Выбор из хранилища
Одной из наиболее часто используемых функций при работе с состоянием является выборка. Выборка — это преобразование вашего состояния, справедливое по соображениям производительности. Вы должны обновлять компоненты представления только тогда, когда обновляются данные, используемые внутри. Это оптимизация рендеринга.
Например, состояние пользователя большое, в нем много пользовательских настроек и прочего. Если у вас есть компонент представления аватара, он должен обновляться только при изменении аватара, а не при каждом обновлении состояния пользователя.
import { box, select } from 'remini'
const $user = box({
name: 'Joe',
email: 'a@x.com',
settings: {},
avatar: 'https://avatar.com/1.jpg'
})
const $avatar = select($user, user => user.avatar)
import { useBox } from 'remini/react'
const Avatar = () => {
const avatar = useBox($avatar)
return (
<img src={avatar} />
)
}
Вы видите, как легко сделать эту крошечную, но очень эффективную оптимизацию!
Вам не нужно рендерить все подряд. Вы должны рендерить только то, что вам нужно! Не больше, не меньше)
Состав магазинов
Шаг за шагом по приложению, растущему вверх, у вас будут появляться случаи необходимого объединения нескольких магазинов в один. Это должно быть просто)
import { box, read, wrap } from 'remini'
const $firstName = box('John')
const $lastName = box('Doe')
const $fullName = wrap(() => {
return read($firstName) + ' ' + read($lastName)
})
Здесь мы объединяем несколько магазинов в один для удобства использования в некоторых компонентах представления.
Ссылки
- Переключатель темного режима
- Общее состояние
- Совместная работа с Redux
- Чистая реактивность в Node.js
Установите
npm install remini
# or
yarn add remini
Наслаждайтесь своим кодом!
Github: https://github.com/re-js/remini
Npm: https://www.npmjs.com/package/remini