UseContext hook provides a way to pass data through the component tree without having to pass props down manually at every level. It helps maintaining cleaner code. In other words – it provides a way to share values between components without having to explicitly pass a prop through every level of the tree.
UseContext hook is useful to share data that can be considered “global” for a tree of React components. Lets create one:
const DataContext = createContext();
const DataContextProvider = (props) => {
const [data, setData] = useReducer(switchData, {
color: "gray",
isTextVisible: false,
})
return (
<DataContext.Provider value={{data, setData}} >
{props.children}
</DataContext.Provider>
)
}
In the example above we created new context (createContext function) and wrapped returned data from DataContextProvider component in Provider component, which allows consuming components to subscribe to context changes. In other words – all components that are wrapped by Provider component has access to data in context (in this case: data variable and setData function).
Lets add same more code: swithData function and DataContextProvider export, and whole dataContext component will be look like this:
dataContext.js:
import React, { createContext, useReducer } from 'react';
export const DataContext = createContext();
const switchData = (state, action) => {
switch (action.type) {
case "changeColor":
return {...state, color: action.color};
case "changeTextVisibility":
return {...state, isTextVisible: !state.isTextVisible};
default:
return state;
}
}
const DataContextProvider = (props) => {
const [data, setData] = useReducer(switchData, {
color: "gray",
isTextVisible: false,
})
return (
<DataContext.Provider value={{data, setData}} >
{props.children}
</DataContext.Provider>
)
}
export default DataContextProvider;
When we created context component using useContext hook, we must wrapped all components, that may use data from context. That’s why we add to our App.js component this code:
App.js:
import React from 'react';
import HookExample from './components/hookExample.js';
import DataContextProvider from './contexts/dataContext.js';
function App() {
return (
<DataContextProvider >
<HookExample />
</DataContextProvider>
);
}
export default App;
Now we can use our context data in other components:
HookExample.js:
import React, { useContext } from 'react';
import { DataContext } from '../contexts/dataContext.js';
const HookExample = () => {
const dataContext = useContext(DataContext);
return (
<div className="App">
<p style={{color: dataContext.data.color}}>This is sample text</p>
<div style={{display: dataContext.data.isTextVisible ? "block" : "none"}}>
This is more text, which is visible if clicked on "Show more text" button
</div>
<div>
<button onClick={() => dataContext.setData({type: "changeColor", color: 'red'})}>Change text color</button>
<button onClick={() => dataContext.setData({type: "changeTextVisibility"})}>Show more text</button>
</div>
</div>
);
}
export default HookExample;
In HookExample component we used data (data.color, data.isTextVisible variables and setData function) taken from dataContext component, where we created context. In the same way we can use this data in other components, if they are wrapped by DataContextProvider component (which returns our context).
Click on DEMO to see how useContext hook works
You can find this code in repo: https://github.com/love-coding-pl/React-Hooks-Examples/tree/Hook-3-useContext
Thanks. This helped, much more to the point and newer than a lot of other posts on useContext and createContext.
Great Thank you so much