Context API: Why and How

Motivation:

One of the key features of React is one-way data binding which enables us to send props data from only parents to children. This is very useful as it’s easy to understand from where the data is passed into that component. But imagine a situation, where we are required to send data to more than 5 layers down!

The code starts to get messy from now on. Besides, it requires a lot of code repetition, unnecessary data passing to children which don’t need the data for themselves but to pass to their children, and difficult to maintain. This scenario is termed ‘prop drilling’.

<div user={user}>  —(1)
  <div  user={user}> —(2) 
    <div  user={user}>  —(3)  
      <div  user={user}>  —(4)
        <div  user={user}>  —(5)
          <div  user={user}>  —(6)
         <div  user={user}> —(7)
           <h2> {user.name} </h2>
             <div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

From the above abstraction, we see the prop is drilled to 7 layers down to get the user props data which is very difficult to keep track of. There is a better approach to avoid this situation which is using context API. Context API is used to create centralized data, much like global variables which can be accessed from anywhere. One may think of Redux(acts like a store that stores data and the store can be accessed from anywhere), but that is used in large and complex applications that require a lot of states to maintain. But that’s another story, we will stick to context API for now.

How to use:

  1. First, we will create a folder in the src folder named contexts (not required. just a convention)
  2. Now, we will create a provider, our case it’s AuthProvider. I will use functional component for this tutorial. So, let’s create AuthProvider component like so.
import React from 'react';
  const AuthProvider = () => {
    return (
        <div>         
        </div>
    );
  };
  export default AuthProvider;
  1. Now create a context (AuthContext) above the AuthProvider component and rename ‘div’ inside the component to AuthContext.Provider like so.
import AuthProvider from './Context/AuthProvider';
import User from './Component/User';
function App() {
  return (
    <div>
      <AuthProvider>
        <h2>Context API intro</h2>
        <User></User>
      </AuthProvider>
    </div>

  );
}
export default App;

React provides createContext API, which Creates a Context object. When React renders a component that subscribes to this Context object it will read the current context value from the closest matching Provider above it in the tree.
Notice, the created AuthContext is used is AuthProvider and provided a user as value. Also, children is taken as props and AuthContext is exported as the context will be consumed later.

  1. So far we have created a context and provided a value to the AuthProvider. Now we will create a custom hook inside a hooks folder named useAuth, where we will consume the context like so
import { useContext } from "react";
import { AuthContext } from "../Context/AuthProvider";
const useAuth = () => useContext(AuthContext)
export default useAuth;

useContext hook is used to consume the context we created earlier.

  1. Use AuthProvider component to the top of App.js so that every children gets access to the context api provided value. Meanwhile, create another component inside component folder named User.js like so
import AuthProvider from './Context/AuthProvider';
  import User from './Component/User';
  function App() {
    return (
      <div>
        <AuthProvider>
          <h2>Context API intro</h2>
          <User></User>
        </AuthProvider>
      </div>
    );
  }
  export default App;
  1. Now we will use the context api provided value using the custom hook useAuth and display the user info.
import React from 'react';
 import useAuth from './../hooks/useAuth';
 const User = () => {
    const user = useAuth()
    console.log(user);
    return (
        <div>
            user name: {user.name}
        </div>
    );
 };
 export default User;

Finally, we have access to the value that was provided in the AuthProvider.

All the corresponding codes will be available here.

33