React
by Niels Krijger
HTML
<div id="app"></div>
CSS
h1 {
font-size: 2em;
font-weight: bold;
}
h2 {
font-size: 1.5em;
font-weight: bold;
}
.block {
padding: 1em;
}
React
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
default:
return state;
}
}
const initialState = {
count: 0,
};
const MyContext = React.createContext();
const MyContextProvider = ({ children }) => {
const [state, dispatch] = React.useReducer(reducer, initialState);
return (
<MyContext.Provider
value={{ state, dispatch }}
>
{children}
</MyContext.Provider>
);
};
let component1RenderCount = 0;
const Component1 = () => {
component1RenderCount += 1;
const { dispatch } = React.useContext(MyContext);
return (
<div className="block">
<button type="input" onClick={() => dispatch({ type: 'increment' }) }>Button 1</button>
Component1 renders: {component1RenderCount}
</div>
);
}
let component2RenderCount = 0;
const Component2 = () => {
component2RenderCount += 1;
const { dispatch } = React.useContext(MyContext);
return (
<div className="block">
<button type="input" onClick={() => dispatch({ type: 'increment' }) }>Button 2</button>
Component2 renders: {component2RenderCount}
</div>
);
}
const StateCount = () => {
const { state } = React.useContext(MyContext);
return (
<h2>Counter: {state.count}</h2>
)
};
const App = props => {
return (
<MyContextProvider>
<h1>Subscribing to context state</h1>
<StateCount />
<Component1 />
<Component2 />
</MyContextProvider>
);
};
// -- Split it in two
const StateContext = React.createContext();
const DispatchContext = React.createContext();
const MyComplexContextProvider = ({ children }) => {
const [state, dispatch] = React.useReducer(reducer, initialState);
return (
<DispatchContext.Provider value={dispatch}>
<StateContext.Provider value={state}>
{children}
</StateContext.Provider>
</DispatchContext.Provider>
);
};
let component3RenderCount = 0;
const...