React Duck
![Coverage Status](https://coveralls.io/repos/github/iamogbz/react-duck/badge.svg?branch=master)
Implement ducks in React following the redux pattern but using React Context.
Usage
Create the ducks for each slice of application logic.
export default createDuck({
name: "counter",
initialState: 0,
reducers: {
increment: (state) => state + 1,
},
});
Create the root/global duck as a combination of all other ducks.
export default createRootDuck(counterDuck, otherDuck);
Create the global context.
export default createContext(rootDuck.reducer, rootDuck.initialState);
Use the state and actions in your component.
export default function App(props) {
const { state, dispatch } = React.useContext(Context);
const increment = React.useCallback(
() => dispatch(counterDuck.actions.increment()),
[dispatch]
);
return (
<div>
Count: <span>{state[counterDuck.name]}</span>
<button onClick={increment} />
</div>
);
}
Note: this is equivalent to the class component described below.
export default class App extends React.PureComponent {
static contextType = Context;
render() {
const { state } = this.context;
return (
<div>
Count: <span>{state[counterDuck.name]}</span>
<button onClick={this.increment} />
</div>
);
}
increment = () => {
this.context.dispatch(counterDuck.actions.increment());
};
}
Wrap the application in the root provider to handle state changes.
const rootElement = document.getElementById("root");
const Provider = createRootProvider(Context);
ReactDOM.render(
<Provider>
<App />
</Provider>,
rootElement
);
Note: createRootProvider
is just a helper and can be replaced, with the functional difference highlighted below.
diff --git a/index.jsx b/index.jsx
index 0a0a0a0..1b1b1b1 100644
--- a/index.jsx
+++ b/index.jsx
const rootElement = document.getElementById("root");
-const Provider = createRootProvider(Context);
ReactDOM.render(
- <Provider>
+ <Provider Context={Context}>
<App />
Example
As a proof of concept converted the sandbox app from the react-redux basic tutorial
Next
- Implement slice selectors and
useSelector
hook, reference - Implement asynchronous middleware context support, reference
- Implement observable pattern for context value, reference
Suggestions
- Use
immer
to create immutable reducers, see guide.