react-hooked-reducer
v0.2.0
Published
> This package is a PoC and in development
Downloads
11
Readme
react-hooked-reducer
This package is a PoC and in development
Use reducers in React, like with useReducer
but with the following additional benefits:
- Receive actions from a
store
- Optionally embed your reducer inside a
store
and fully benefit from Redux developing tools
yarn add react-hooked-reducer
# or
npm install react-hooked-reducer
See it in action on CodeSandbox
Why
Using global reducers for React components has several disadvantages:
- You end up having to manage initialisation or reset actions
- Having multiple instances of a same component requires you to use add and remove actions, to identify actions and to add a wrapping reducer.
The solution is to couple reducers to their component instances, like in react-local-reducer or the newly created react hook useReducer
However, by doing so we loose the developer experience that comes with Redux: inspecting actions and state, time travelling.
This package allows to have the best of both: local reducers with great DX!
Usage
hookedReducersEnhancer
For this package to work, you need to enhance your store with hookedReducersEnhancer
:
import { hookedReducersEnhancer } from "react-hooked-reducer"
const store = createStore(reducer, initialState, hookedReducersEnhancer)
See https://redux.js.org/api/compose for more info on how to compose store enhancers together.
useReducer(reducer, initialState, store, reducerId, hooked)
reducer
: your reducerinitialState
: the initial state for your reducerstore
: your store instancereducerId
: an unique ID to identify your reducerhooked
: iftrue
, your reducer will be "embedded" inside your store.
Things you can do
You can set
hooked
totrue
in development, andfalse
in production: when your reducer is not attached to your store, changes in its state won't cause a new store state to be emitted.You can create your own custom hook to avoid having to pass down
store
: add it to a custom context and then useuseContext
:import { useHookedReducer } from "react-hooked-reducer" import StoreContext from "./context" export default function useReducer(reducer, initialState, reducerId) { const store = useContext(StoreContext) return useHookedReducer( reducer, initialState, store, reducerId, process.env.NODE_ENV === "development" ) }
Example
import { useReducer } from "react-hooked-reducer"
function Counter({ store, id, embedded = false }) {
const [count, dispatch] = useReducer(
(state, action) => {
if (action.type === "+") {
return state + 1
}
if (action.type === "-") {
return state - 1
}
return state
},
0,
store,
id,
embedded
)
return (
<div>
<button onClick={() => dispatch({ type: "-" })}>-</button> {count}{" "}
<button onClick={() => dispatch({ type: "+" })}>+</button>
</div>
)
}