A React hook for reducers that you can run inside a Redux store for great DX
MIT License
This package is a PoC and in development
Use reducers in React, like with useReducer
but with the following additional benefits:
store
store
and fully benefit from Redux developing toolsyarn add react-hooked-reducer
# or
npm install react-hooked-reducer
See it in action on CodeSandbox
Using global reducers for React components has several disadvantages:
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!
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.
reducer
: your reducerinitialState
: the initial state for your reducerstore
: your store instancereducerId
: an unique ID to identify your reducerhooked
: if true
, your reducer will be "embedded" inside your store.You can set hooked
to true
in development, and false
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 use useContext
:
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"
)
}
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>
)
}