Running example:
https://codesandbox.io/s/testing-react-context-46hbn
Original idea taken from:
https://kentcdodds.com/blog/how-to-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
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> | |
); | |
} |