What's this Context in ReactJS everyone's talking about! So according to the React Documentation " Context provides a way to pass data through the component tree without having to pass props down manually at every level."
So we can see it's a way to pass data through the component tree without props at every level. Well isn't it amazing! because it's like having global variables or in react terms something like global props. Let's take an example and go through the Context with React to get a good idea about it.
Very simple usage for such a feature might be using Themes (Dark Theme/Light Theme) for your React Application (NOTE: We must use Context for only the states which would not change regularly). As themes are supposed to be passed to various components to change their appearance on say a click of a button anywhere in the component tree.
Now if we had usual props used to pass the data we might end up in trouble why? Let's say we have one application with a main component within it a brand component and a cards section inside it as shown below:
Now say you have a state maintained in Main Component and then use in cards section so you would have to pass it down all through from main to display and then get it in Cards component. This is a very basic structure and this approach is not very practical in web applications with complex structures.
That's where the React Context comes to the rescue. Context provides a very simple structure for this purpose. Let's walk through the steps for using Context:
- You might have to create a context that we are gonna use for storing the global props and you might wanna do it in a separate component (For example here a theme Context is created).
const ThemeContext = React.createContext();
- Then you have to create a ContextProvider component which would wrap all the components of the app and it must contain all the states that are to be passed to each and every component which is wrapped in it.
export const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState('light');
const [backgroundColor, setBackgroundColor] = useState('bg-gray-100');
const [textColor, setTextColor] = useState('black');
const [cardsBackgroundColor, setCardsBackgroundColor] = useState('bg-white');
const toggleTheme = () => {
if (theme === 'light') {
window.localStorage.setItem('theme', 'dark');
setThemeColor('dark');
} else {
window.localStorage.setItem('theme', 'light');
setThemeColor('light');
}
};
return (
<ThemeContext.Provider
value={{
backgroundColor,
textColor,
cardsBackgroundColor,
toggleTheme,
theme,
}}
>
{children}
</ThemeContext.Provider>
);
};
- So to use Context we actually need to wrap everything inside those Context and we do that generally by wrapping the whole App inside ReactDOM.render().
- Now that's all left is to use Context where we might wanna use it, but before we do that we would require to import Context wherever we want to use it. To keep all the things simple you might wanna expose a custom hook to keep the import of Context minimal.
export const useContextTheme = () => {
return useContext(ThemeContext);
};
- Finally Now we want to use our created Context, for that we would require the custom hook created by us in the previous step we import it and we are free to use it however we wish!
Import the context:
import { useContextTheme } from 'components/ThemeContext';
Use inside your component:
const { toggleTheme, cardsBackgroundColor, theme } = useContextTheme();
Hurray! you are good to go for creating and using your own Contexts!
Top comments (4)
sebmarkbage 2018
Granted the example shown here deals with "locale/theme" data — the issue is that it would be all too easy to get the impression that it is OK to store "regular data" within
context
.For example Redux and MobX simply store an access point that never changes during the entire application session within
context
.That (never changing) access point makes it possible to subscribe to updates from the library runtime. Once the subscribed,
context
is rarely involved in component ⬌ data exchanges.I am Sorry, I should have mentioned about the things me might store in Context (like which changes not on regular basis) and the things we might not.
No need to apologize — for the most part the official docs are silent on the matter and I only became aware of it through Mark Erikson's Why React Context is Not a "State Management" Tool.
Phrased differently: Context is a place for "first introductions" between components and cross-component state (management) but not for "regular meetings" between them.
In my opinion the countless "don't need Redux, just use Context" statements communicate a misunderstanding of what context actually is.
There are "lighter" (cross-component) state management solutions like unistore, valtio, zustand and jotai.
Nicely done. This makes me want to use context more.