Guide to React Context API in Functional Components
Tags: webdev, react, contextapi, tutorial
Published: 2023-01-19 12:45:04


## Introduction

The Context API in React is a way for a component to share data with other components without having to pass props down through multiple levels of the component tree.
Imagine that you have a small application with a bunch of components, and some of these components need to use the same piece of data. Without the Context API, you would have to pass this data down as props through all the intermediate components, even if they don't need that data. This can get really messy and hard to understand, especially if you have a lot of components and a deep component tree.
The Context API makes it easier to share data by creating a "context" where you can put the data. You can then use a special component called a "Provider" to make this context available to any component that needs it. Any component that needs to use the data from the context can then use a special component called a "Consumer" to access the data.

### Why context API

The React Context API is useful for cases where you have data that is needed by many components within an application, and you want to avoid the prop drilling that would be required to pass the data down through the component hierarchy.
One advantage of using the Context API over using the state is that it allows you to centralize your application's state and make it easier to manage. This can be especially useful in larger applications where you have a complex component hierarchy and you need to pass data down through multiple levels of components.
Another advantage of using the Context API is that it can improve the performance of your application by avoiding unnecessary re-renders of components that are deep in the component tree. When using the Context API, a component will only re-render if the value it receives from the context has changed. This can help to reduce the number of unnecessary re-renders in your application and improve its overall performance.
Overall, the decision to use the Context API or state in a React application will depend on the specific needs of your application and how you want to manage and organize your application's data.

### When to use Context API

It can be used in a variety of situations where you want to avoid prop drilling and centralize your application's state.
Some examples of when you might consider using the Context API include:

- When you have data that is needed by many components within your application, and you want to avoid passing it down through the component hierarchy as props.
- When you want to avoid the performance overhead of unnecessary re-renders caused by prop changes deep in the component tree.
- When you want to centralize the management of your application's state in a single location.
- When you want to make it easier to test your components by providing them with mocked or dummy data.
- You have a large application with a complex component hierarchy and you need to pass data down through multiple levels of components.
- You have data that is global to your application and needs to be accessed by many different components.
- You want to centralize your application's state and make it easier to manage.
- You want to avoid unnecessary re-renders of components that are deep in the component tree and improve the performance of your application.

It is important to carefully consider whether the Context API is the right tool for your specific use case before implementing it in your application.

### States and Props in React
Before we go deep into how to set up context API, lets talk about state and props in react JS. Props and state are closely related to the Context API in React, as they are all used to manage and pass data between components. 

- Props: Props (short for "properties") are used to pass data from a parent component to a child component. Props are passed to a component as an attribute when it is being rendered. For example, the following code creates a component that accepts a "name" prop and displays it on the screen:

```
    import React from 'react';
    
    const Greeting = (props) => {
      return <h1>Hello, {props.name}!</h1>;
    }
    
    const element = <Greeting name="Daniel" />;
```

Here, the "name" prop is passed to the Greeting component as an attribute. The component then uses the value of the prop to render the greeting.


- State: is used to store and manage data that is local to a component. Unlike props, state is managed by the component itself and can be changed over time. The component can update its state using the `setState()` method, and it will re-render itself to reflect the changes. 
For example, the following code creates a component that keeps track of a counter and has a button that increments the counter when clicked:

```
    import React, { useState } from 'react';
    
    const Counter = () => {
      const [count, setCount] = useState(0);
      return (
        <div>
          <h1>{count}</h1>
          <button
          onClick={
            () => setCount(count + 1)
          }>Increment</button>
        </div>
      );
    }
```

In this example, the component uses the `useState()` hook to create a state variable called "count" with an initial value of 0. When the button is clicked, the component calls `setCount(count + 1)` to update the count and re-render the component.

Basically, props are used to pass data from a parent component to a child component, while state is used to store and manage data that is local to a component, and it can change over time.
Context API shares data between components ( like Props ) in a more efficient way and it can also help you manage information that many parts of your application need to access (like global state)

### How to use Context API

To use the React Context API, you can use the React `useContext` hook, which allows you to access the current context value within a component.
How to set up context API
These steps will guild you on how to set up a simple context API for your application.

- Create a folder in your project directory and name it context ( This is optional as you can create your context anywhere in the app but for easy management, it is better to keep it in its own folder)
- Create a file named after your component and append Context.js, e.g. blogContext.js.
- In the newly created file, import `createContext` from the React library

```
    import React, { createContext } from "react";
    export const BlogContext = createContext();
```

- Create a component in the context file that will serve as the provider of the data in your context to components that are descended from it using a Provider component. The Provider component takes a value prop, which is the value that you want to provide to the components that are descended from it. In this case, we passed a React state, so that we can access and also update the value of our context API.

```
    const BlogProvider = ({ children }) => {
    
      const [blogState, setBlogState] = useState({
        loading: false,
        title: "Hello",
        message: "This is a post on context api",
      });
    
    return (
       <BlogContext.Provider value={[blogState, setBlogState]}>
          {children}
       </BlogContext.Provider>
    )};
    
    export default BlogProvider;
```

- To access the data in the provider, you need to wrap your app with it.

```
    import React from "react";
    import BlogProvider from "../Link-To-Provider/"
    
    const BlogProject = () => {
      return (
        <BlogProvider>
          <Blog />
        </BlogProvider>
      );
    };
    
    export default BlogProject;
```

That's basically how to set up a context API in React.
How to get data from context API
The useContext hook is a way to access the current context value within a functional component in React. It allows you to access the value of a context object within a functional component. 
Below are the steps to get data from your context provider.

- Inside the component file where you want to use the data in your context provider, import the `useContext` hook from the React library

```
   import React, { useContext } from "react"; 
```

- Now import your Provider value from your context, in the case it's `blogState` which contains the value and `setBlogState` which we will be using later to update our context API.

```
    import BlogProvider from "../Link-To-Provider/";
    
    const Post = () => {
    
    const [blogState, setBlogState] = useContext(AppContext);
    
    }
```
- You now have access to your context data through `blogState`. You can choose to destructor and get only the values you need or use them directly. In the example below we'll be rendering the Title and Message values on the dom.

```
    const Post = () => {
    
      const [blogState, setBlogState] = useContext(AppContext);
    
      const { title, message } = blogState;
    
      return (
           <div>
              <h3>{title}</h3>
              <p>{message}</p>
           </div>
      );
    };
    
    export default Post;
```

That is how you fetch data from your context API.
How to update or save data to context API
We can also update and save data to our context using the `setBlogState` we created earlier. Remember we had a useState hook in our context API file with `blogState` to hold the current value of our state and `setBlogState` to update the value of the state which is also our Context API. Below are the steps to update the context API

- Inside the component file where you want to update the data in your context provider, import the `useContext` hook from the React library

```
    import React, { useContext } from "react";
```

- Now import your update state function, in our case it's `setBlogState`.

```
    import BlogProvider from "../Link-To-Provider/";
    
    const Post = () => {
    
    const [, setBlogState] = useContext(AppContext);
    
    }
```

- You now have access to update your context data through `setBlogState`. You can update all data in the context or just a particular value. In the examples below we'll be updating all the data in our context API and also a single value.

```
    const Post = () => {
    
      const [, setBlogState] = useContext(AppContext);
    
    
      const updateAllState = () => {
       setBlogState(
        {
          loading: true,
          title: "Good Bye",
          message: "Just want to say i will miss you!",
        }
       )
      };
    
      return (
           <div>
              <h3>{title}</h3>
              <p>{message}</p>
           </div>
      );
    };
    
    export default Post;
```

In the code block above, calling the function `updateAllState` will change the initial values of our context API. There are also cases where you might just want to change a single value, here is how to do it.

```
    const Post = () => {
    
      const [, setBlogState] = useContext(AppContext);
    
    
      const updateTitle = () => {
       setBlogState(prevState => ({
        ...prevState,
        title: "Its a new Title",
       }));
      };
    
      return (
           <div>
              <h3>{title}</h3>
              <p>{message}</p>
           </div>
      );
    };
    
    export default Post;
```

With react hooks, You can use the functional form of setState and the prevState argument to update a single value in the state object. The functional form of setState takes a callback function which receives the previous state as an argument and returns the new state. To update a single value in the state object, you can use the object spread operator (...) to create a new object with the updated value and the rest of the properties from the previous state. In our case, we spread the previous state in our context API and then update just the `title`.

### Conclusion
In this article, we discussed the use of the Context API in functional components as an alternative to props drilling. We learned how the Context API allows for easy management of component state and sharing of state across multiple components without the need for props drilling. This approach improves code readability and maintainability. Additionally, the use of hooks in functional components makes it easy to integrate the Context API into functional components. Overall, the Context API is a powerful tool that can simplify state management in functional components and improve the overall structure of your code.