An Interest In:
Web News this Week
- April 20, 2024
- April 19, 2024
- April 18, 2024
- April 17, 2024
- April 16, 2024
- April 15, 2024
- April 14, 2024
Storecle - a neat app state management for React and Solid
Storecle is a neat uni-directional app state management for React and Solid ().
Features
Storecle uses a simple mental model which lets you access app-wide actions and their results by using Context API.
It consists of 4 main building blocks i.e. Store, User Actions (actions triggered by a user), Data Suppliers (actions executed prior to rendering) and Reload Types (action re-trigger groups).
The actions are just functions which are implicitly bound to the Store and write their results by returning/resolving.
Then, their results are accessible by their own names.
To improve the code re-usability, Data Suppliers use a middleware pattern. They are executed in the order you specify and pass a snapshot of Store from one to another, letting you split the logic into small, specified functions.
- It works with both React and Solid (it's framework agnostic to certain degree).
- It uses Context API and
useEffect
/createEffect
to provide action re-triggers based on specified Store changes. - It facilitates splitting the business logic into granual, re-usable functions by applying a middleware pattern.
- It simplifies naming and reduces noise by letting you access action results by their own names.
- It provides an elegant approach to actions feeding UI with incoming data (e.g. from Web Sockets).
- It is made to work with your IDE's code auto-completion.
Motivation
I Redux, but it leaves plenty of room to be misused. Hence, Storecle is my proposal to let developers rely less on self-discipline and more on tooling and self-restrictive design.
- To provide an easy way of separating app-wide logic from views i.e.:
- No inline: data fetches, transformers, conditionals.
- No nested action dispatchers upon other action completion.
- To facilitate the action re-usability and modularization.
- To provide a gradual path for React developers willing to use Solid.
Installation
React:
yarn add @gluecodes/storecle-react
or
npm i @gluecodes/storecle-react
Solid:
yarn add @gluecodes/storecle-solid
or
npm i @gluecodes/storecle-solid
It works along with either React or Solid that also needs to be installed in your app. For details, see their own documentations.
Usage
This module exports 3 constructs that can be imported for a particular framework in different parts of your app.
import { builtInActions, PageProvider, useAppContext } from '@gluecodes/storecle-react'
or
import { builtInActions, PageProvider, useAppContext } from '@gluecodes/storecle-solid'
For the purpose of the example I used a Solid version.
Soon the official starter templates will be released. Using this library means following certain patterns which are explained below using a simple counter example.
Mental Model
See: Code Sandbox example for React.
See: Code Sandbox example for Solid.
File tree:
. actions dataSuppliers (#2) index.js reloadTypes.js (#4) userActions (#3) index.js index.jsx (#1) Layout.jsx (#5) partials (#6) Counter index.jsx
1. Page Container
Page provider wraps a given Layout around a single app context.
dataSupplierPipeline
- an array providing the order in which Data Suppliers are executed.dataSuppliers
- an object containing Data Suppliers.getLayout
- a function which returns the page Layout.reloadTypes
- an object containing Reload Types.userActions
- an object containing User Actions.onError
- a function triggered when an error is thrown either in Data Suppliers or User Actions.
./index.jsx
import { PageProvider } from '@gluecodes/storecle-solid'import * as dataSuppliers from './actions/dataSuppliers/index'import * as userActions from './actions/userActions/index'import * as reloadTypes from './actions/reloadTypes'import Layout from './Layout.jsx'export default () => ( <PageProvider dataSupplierPipeline={[ dataSuppliers.getTexts, dataSuppliers.getCounter ]} dataSuppliers={dataSuppliers} getLayout={() => Layout} reloadTypes={reloadTypes} userActions={userActions} onError={(err) => { console.error(err) }} />)
2. Data Suppliers
Data suppliers provide data prior to rendering. Note the early returns which demonstrate how to resolve cached data based on Reload Type.
buildInActions
- an object containing the following built-in User Actions:onStoreChanged
- a function which receives a callback to be triggered when Store changes.runUserActions
- a function which allows for executing multiple User Actions at once.runDataSuppliers
- a function which receives a Reload Type name. Note that it's exposed to ease the integration with legacy apps. Don't call it manually as Data Suppliers are implicitly reloaded based on the provided Reload Types.
- Each Data Supplier passes two arguments:
resultOf
andnameOf
.resultOf
- a function providing a result of a given Data Supplier or User Action.nameOf
- a function providing a name of either Data Supplier, User Action or Reload Type.
- Data Suppliers can be either sync or async and write to a central Store by returning/resolving.
./actions/dataSuppliers/index.js
import { builtInActions } from '@gluecodes/storecle-solid'import { reFetchCounter } from '../reloadTypes'export function getCounter (resultOf, nameOf) { const reloadType = resultOf(builtInActions.runDataSuppliers) const shouldFetch = reloadType === 'full' || reloadType === nameOf(reFetchCounter) if (!shouldFetch) { return resultOf(getCounter) } return global.sessionStorage.getItem('appWideCounter') || 0}export function getTexts (resultOf) { if (resultOf(builtInActions.runDataSuppliers) !== 'full') { return resultOf(getTexts) } return { Click: 'Click' }}
3. User Actions
Actions triggered by a user.
./actions/userActions/index.js
export function incrementCounter (counter) { const incrementedCounter = Number(counter) + 1 global.sessionStorage.setItem('appWideCounter', incrementedCounter)}
4. Reload Types
A way to tell the app to re-run Data Suppliers based on executed User Actions.
- A Reload Type groups User Actions together to tell the app to reload all Data Suppliers as a consequence of their execution.
- When any of its User Actions is triggered, the app sets the Reload Type name under built-in
runDataSuppliers
and reloads all Data Suppliers. - Data Suppliers can benefit from caching by early returning their results based on Reload Type name.
- Each Reload Type is a function which passes
nameOf
and returns an array of User Action names.nameOf
- a function providing a name of User Action.
./actions/reloadTypes.js
import { incrementCounter } from './userActions/index'export const reFetchCounter = (nameOf) => [ nameOf(incrementCounter)]
5. Layout
Nothing else than the page layout.
./Layout.jsx
import Counter from './partials/Counter/index.jsx'export default () => ( <div className='container'> <Counter /> </div>)
6. Partials
Partials are self-contained pieces of UI which have access to app state via the app context.
useAppContext
- a function which returns an array of 3 items:resultOf
,action
,nameOf
.resultOf
- a function providing a result of a given Data Supplier or User Action.action
- a function which triggers User Action.nameOf
- a function providing a name of either Data Supplier or User Action.
./partials/Counter/index.jsx
import { useAppContext } from '@gluecodes/storecle-solid'import { getCounter, getTexts } from '../../actions/dataSuppliers/index'import { incrementCounter } from '../../actions/userActions/index'export default () => { const [resultOf, action] = useAppContext() return ( <button onClick={() => { action(incrementCounter)( resultOf(getCounter) ) }} >{resultOf(getTexts)?.Click}: {resultOf(getCounter)}</button> )}
Here is the open source Github repo. Feel free to suggest your ideas either in comments or in the repo issues. If you like it, a star would be appreciated
Original Link: https://dev.to/chrisczopp/storecle-a-neat-app-state-management-for-react-and-solid-52ak
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To