Basic useContext + useReducer
by Niels Krijger
HTML
<div id="app"></div>
CSS
body {
background-color: #F2F5F6;
font-family: sans-serif;
}
button {
min-width: 3em;
height: 2em;
text-align: center;
}
h1 {
font-size: 2em;
font-weight: bold;
padding-bottom: .3em;
}
h2 {
font-size: 1.5em;
font-weight: bold;
}
div {
padding: .5em 1em;
}
React
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
return state;
}
}
const MyContext = React.createContext();
const MyContextProvider = ({ children }) => {
const [state, dispatch] = React.useReducer(reducer, { count: 0 });
return (
<MyContext.Provider
value={{ state, dispatch }}
>
{children}
</MyContext.Provider>
);
};
let buttonIncreaseRenders = 0;
const ButtonIncrement = () => {
buttonIncreaseRenders += 1;
const { dispatch } = React.useContext(MyContext);
return (
<div className="block">
<button type="input" onClick={() => dispatch({ type: 'increment' }) }>+ 1</button>
This button rendered {buttonIncreaseRenders} times
</div>
);
}
let buttonDecreaseRenders = 0;
const ButtonDecrement = () => {
buttonDecreaseRenders += 1;
const { dispatch } = React.useContext(MyContext);
return (
<div className="block">
<button type="input" onClick={() => dispatch({ type: 'decrement' }) }>- 1</button>
This button rendered {buttonDecreaseRenders} times
</div>
);
}
const StateCount = () => {
const { state } = React.useContext(MyContext);
return (
<div className="block">
<strong>Counter: {state.count}</strong>
</div>
)
};
const App = props => {
return (
<MyContextProvider>
<h1>Basic useContext + useReducer</h1>
<StateCount />
<ButtonIncrement />
<ButtonDecrement />
</MyContextProvider>
);
};
ReactDOM.render(<App />, document.getElementById('app'));