Key Takeaways
In this article, we will learn more about React context API.
You will also see brief information on how the Context API works
We will discuss why the Context API is needed.
Also, learn how the Context API is used.
Conext API is a feature added in React v16.3 that helps developers to share the state throughout the app with ease.
React Context API solves different state management problems that modern apps face; for instance- props drilling. There are other solutions available for solving state management issues along with props drilling, but they can make you compromise the app performance by increasing the build size.
Context API is an in-built React feature. So, it doesn’t affect the performance and avoids creating library installation issues. It is basically a structure that helps you to pass data regarding specific details and also helps you avoid prop drilling from all phases of your app.
In this article on React Context API, we will explore more about what the context API is, how to use it, how it works, and when it is needed.
Let’s dive in!
What is React Context API?
The React context API is an API that helps the React applications to produce global variables effectively that are easy to pass around. It is an alternative to prop drilling in which props are moved from grandparent-child-parent in a component tree. Moreover, it is a lighter and easier approach to perform state management by using Redux.
Basically, Context API gives a way to pass data in the React components tree rather than to pass props down manually on each level.
In a traditional React app, data passes from parent -> child using props. But such a process can become cumbersome for specific props that are needed by multiple components in the app. Context shares these values in-between the components without specifically passing a prop on each level of the component tree.
Now, let's discuss how the React Context API works.
How does the Context API works?
All you need is a context object created using React.createContext(). This method returns a provider component & one consumer component. Provider component provides the state to child components. It can hold/store and become the parent component of the majority of components that needs a store.
The consumer is the component that uses the state and consumes it. You can read more about this topic on the official React documentation page.
Context API can pass the data in the component tree without using props manually at each level. This process makes it easier to share information from a component to another.
For instance, let's suppose you own an eCommerce app with a component showing a customer's shopping cart, & another component showing a customer's order history.
Using Context API, one can develop a context that holds the user's data like cart data and order history. Hence, one can use the same context in both order history and shopping cart components. There's no need to pass the data using props.
Context API is like a big box holding almost everything that you will require for a trip. You can withdraw things from the box and also put them back in the box whenever required.
Primarily, Context API has two basic components, i.e., context provider react component & context consumer react component. With the provider component, one can create and manage context holding the information to share between components. Also, the consumer component is used for accessing this context along with the data from within.
In this example, the provider component creates the context which holds the customer's shopping information, and the consumer component can access the component for getting the customer data whenever needed. This process doesn't require any props and makes the code more easier and efficient to manage.
Why Use Context API?
Here we will understand when and why to use the context API.
This API provides you with one dependency injection system that is based on your component tree. This process was not possible before in React and also integrates the function components with hooks. It's easy to use encapsulated logic for translated alternatives that have react-intl, and also use the context internally. In such matters, where configuration and login are required to be accessed by various components; but are dependent on external modules, using their own Context can be fruitful.
For instance, the user interfaces library needs to work independently from the apps that are using it, but still needs a smoother way to share data than sharing it using props. The tree-based scoping of the UI library is very useful because one can override the component's theme in just one part of the app. You can also take the example of one calendar component that has components and logic. In such cases, we can develop various contexts that assist us to manage and maintain different internal configurations and events and they will not get affected by other widget instances.
When to use Context API?
Context API is made to share information that is "global data" for a React component tree, like- the present authenticated user, preferred language, or theme. For instance, here's the code that is threaded manually through a theme prop for styling one Button component:
class App extends React.Component {
render() {
return <Toolbar theme="dark" />;
}
}
function Toolbar(props) {
// Here the Toolbar component can take one extra "theme" prop
// and further pass it to the ThemedButton.
// It can be painful if each button in the application has to know the theme
// as it has to be passed from one to another component.
return (
<div>
<ThemedButton theme={props.theme} />
</div>
);
}
class ThemedButton extends React.Component {
render() {
return <Button theme={this.props.theme} />;
}
}
This is the example that is made without using Context, with props. Now, we will see the code that uses Context API, and avoids props.
// Context API lets us pass the value in the class based component of the component tree
// without specific threading in every component.
// Make a context for the present theme (it has "light" as the default value).
const ThemeContext = React.createContext('light');
class App extends React.Component {
render() {
// Now use a Provider for passing this theme to the component tree below.
// Every component can easily read it, no matter how deep it is.
// In this example, we're passing "dark" as the current context value.
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
}
// A component when encountered in the middle doesn't have to
// pass the data theme down explicitly.
function Toolbar() {
return (
<div>
<ThemedButton />
</div>
);
}
class ThemedButton extends React.Component {
// Give a contextType for reading the current theme's context.
// React framework will find the nearest theme Provider and use its value.
// We have taken the "dark" theme in this example.
static contextType = ThemeContext;
render() {
return <Button theme={this.context} />;
}
}
How to use Context API?
Here's what you might be thinking: "The above information has convinced me to use Context API. But how to implement Context API?"
Firstly make sure that there's a requirement for Context in your app. Sometimes, developers utilize shared states through the nested components rather than using props. And if there's a need of using Context API, here are the steps of how to use it:
Make a folder in your app root and name it 'contexts'
Develop a file and name it <context name>Context.js, for instance- userContext.js
Create and import it like this:
import React, { createContext } from "react"; const UserContext = createContext();Now, create one component that wraps the provider with the name Provider, for instance- UserProvider. Here's an example of setting a UserProvider using React Hooks.
const UserProvider = ({ children }) => {
const [name, setName] = useState("Jeffery Sebestian");
const [age, setAge] = useState(1);
const happyBirthday = () => setAge(age + 1);
return (
<UserContext.Provider value={{ name, age, happyBirthday }}>
{children}
</UserContext.Provider> );
};
- Now make one higher component to get the context named- withUser. Here's the example made using React Hooks:
const withUser = (Child) => (props) => (
<UserContext.Consumer> {(context) => <Child {...props} {...context} />}
{/* Other alternative is: {context => <Child {...props} context={context}/>}*/}
</UserContext.Consumer> );
The contrast between the two alternatives mentioned in the above code is when you need the API to be a single nested property using this name, for exploding it to the properties.
- Now, export them.
export { UserProvider, withUser };
- Now, use this context whenever and however you want. For instance:
ReactDOM.render( <UserProvider> <App /> </UserProvider>, document.getElementById("root") );
export default withUser(LoginForm);
React Context API- Final Verdict
If you feel that Redux is being overused, you can switch to Context API. But, do not overuse it too. Use context only when there's a need to share state throughout the components using a lot of nesting. Mostly, the data of one component will be relevant only to its children. Hence, passing it using props can also be a good alternative. Or else, using Context API is always a good choice for developers.