React-State-Reducer
A simple (non-feature complete) ~clone~ reimplementation of Redux built using React 16.3's createContext
.
Example:
import React Fragment from 'react'import createStore from 'react-state-reducer' const INITIAL_STATE = count: 0 const counterReducer = state = INITIAL_STATE switch actiontype case 'INC': return count: statecount + 1 case 'DEC': return count: statecount - 1 default: return state const Provider Consumer = <Provider> <Consumer> count dispatch <Fragment> <button => - </button> count <button => + </button> </Fragment> </Consumer> </Provider>
API:
There are two core parts of react-state-reducer's API that should be kept in mind.
Reducers:
The first is the reducer
. A reducer
is a higher order function (meaning it returns a function), that first accepts an action
and returns a function that accepts the current state (and optionally any props provided to the <Provider>
). This returned function should then handle returning the updated state.
That was a lot of different words describing what this is, lets look at some code to walk through this.
- Lets start with the higher order function:
const myReducer = { return { ... }}
This function accepts a single argument (someAction
) and returns a function. Which in turn accepts a single argument called state
. This is often written as the following:
const myReducer = { ... };
- Handling updates within the returned function:
const myReducer = { if action === 'SOME_UPDATE' return ...state someKey: '🆒' }
Some notes with this implementation above:
-
It doesn't follow the generic Redux reducer concept of using a
switch
you can handle writing this function however you would like (usingswitch
, or using an if/else) -
Right now we are implicitly returning
undefined
ifaction
does not equal'SOME_UPDATE'
, while this is valid, you should make sure to at least handle returning the initial state if the action is the following shape:
type: '@@INIT' payload: null
What this looks like in practice:
const todoReducer = { }
createStore
:
createStore
is the main export of react-state-reducer, it is a function that accepts a reducer
as an argument. It calls the reducer with the initialization action:
null
and then uses the result of calling the reducer as the initial state for the store. createStore
then returns an object with the following:
Provider: Node Consumer: Node
Provider
The Provider component exposes two props, the first is children
which can be a single component, or many components.
The second prop is onUpdate
which is a function that will be called after each state update happens, it is called with the updated state.
<Provider => <App /></Provider>
Consumer
The Consumer component has one core prop, children
, children is a function that gets called with an object with the following keys:
dispatch
- top level keys from state
For example if your state shape looks like this:
todos: text: ''
the consumer children function would look like the following:
<Consumer> dispatch todos text ... </Consumer>
Consumer also optionally supports a selector
prop, which can either take in an array of functions or a single function to select your slice of state you care about:
<Consumer => dispatch todos /* */ </Consumer>
Redux
This library is highly influenced by all the great work put into Redux and React-Redux. For some more information on the differences between this library and Redux see redux.