Skip to content

Instantly share code, notes, and snippets.

@jrobinsonc
Last active October 22, 2021 21:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jrobinsonc/1dad2179ea633debbe073729d567e469 to your computer and use it in GitHub Desktop.
Save jrobinsonc/1dad2179ea633debbe073729d567e469 to your computer and use it in GitHub Desktop.
Use React Context effectively

Use React Context effectively

Running example:
https://codesandbox.io/s/testing-react-context-46hbn

Original idea taken from:
https://kentcdodds.com/blog/how-to-use-react-context-effectively

⚠️ Have in mind this is not a good way to keep the state of a whole application, since every component consuming the context will re-render every time the state is changed; this is more to be used in a group of components that should use the same state, like a datagrid, which could need a header, a footer, columns, rows, and all them needs updated to display the new data.

import Left from "./Left";
import Right from "./Right";
import { AppProvider } from "./context";
export default function App() {
return (
<div>
<h1>Testing React Context</h1>
<AppProvider>
<div className="board">
<Left />
<Right />
</div>
</AppProvider>
</div>
);
}
import { useMemo, useContext, useState, createContext } from "react";
const AppContext = createContext();
function AppProvider(props) {
const initialState = {
left: 0,
right: 0
};
const [state, setState] = useState(initialState);
const store = useMemo(() => {
const dispatch = (newState) => {
let parsedNewState = newState;
if (typeof newState === "function") {
parsedNewState = newState(state);
}
setState({
...state,
...parsedNewState
});
};
return { state, dispatch };
}, [state]);
return <AppContext.Provider value={store} {...props} />;
}
function useAppContext() {
const context = useContext(AppContext);
if (context === undefined) {
throw new Error("useAppContext must be used within a AppProvider");
}
return context;
}
export { AppProvider, useAppContext, AppContext };
import { useAppContext } from "./context";
export default function Left() {
const { state, dispatch } = useAppContext();
return (
<div class="board__left">
<h3>Left</h3>
{state.left} <br />
<button
onClick={() => {
dispatch((currentState) => ({ left: currentState.left + 1 }));
}}
>
+
</button>
</div>
);
}
import { useAppContext } from "./context";
export default function Right() {
const { state, dispatch } = useAppContext();
return (
<div class="board__left">
<h3>Right</h3>
{state.right} <br />
<button
onClick={() => {
dispatch({ right: state.right + 1 });
}}
>
+
</button>
</div>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment