The Provider
import React from 'react';
// Creates the context itself. Intialization is needed for autocomplete.
export const ThemeContext = React.createContext({theme:'', toggleTheme: () => {}});
export default function ThemeContextProvider({children}) {
// Create the state in the provider itself
const [theme,setTheme] = React.useState('light');
// define function usable in the context (altering the state)
const toggleTheme = () => {
setTheme(
(currTheme)=>{return currTheme==='light'?'dark':'light';
});
}
const cxtValue = {
theme: theme,
toggleTheme
}
// return a wrapped provider with its values
return <ThemeContext.Provider value={cxtValue}>
{children}
</ThemeContext.Provider>
}
Adding the Provider to the app
import Page from './Page';
import ThemeContextProvider from './ThemeContextProvider.js'
function App() {
return <ThemeContextProvider>
<Page />
</ThemeContextProvider>;
}
export default App;
Altering the state in the provider
You simply use the functions you added to the Provider
import React from 'react';
import {ThemeContext} from './ThemeContextProvider';
export default function Header() {
// use the imported context
const themeCtx=React.useContext(ThemeContext);
return (
<header>
<h2>React Context demo</h2>
<button onClick={themeCtx.toggleTheme}>Toggle Theme</button>
</header>
);
}
Consuming the values from the Provider
Same game :
import Header from './Header';
import React from 'react';
import {ThemeContext} from './ThemeContextProvider';
export default function Page() {
// use the imported context (same)
const themeCtx = React.useContext(ThemeContext);
return (
<div id="app" className={themeCtx.theme}>
<Header />
<article>
<p>
Managing a state using a Provider and React Context
</p>
</article>
</div>
);
}