How to use React Context API with React Hooks

React context is a feature of React that allows data to be accessed through multiple levels of child components. The Context API is similar to React props however unlike props, context needs to be configured only once instead of being passed every time a child component is used.

context api with hooks
React Context with hooks, source: betterprogramming.pub

Defining React Context provider

The first step in configuring context is to define a Context provider which we will use in upcoming steps to configure Context to the whole application.

Inside the context provider, we can declare all the variables, State, etc which needs to be part of the React context. Next, a single AppContext object is declared which consists of all variables, states, etc as properties. Finally, the context provider is wrapped around all the child props with a “value” parameter where the context object is passed.

import React, { createContext, useContext, useState } from 'react';

const AppContext = createContext(undefined);

// Hook to provide access to context object
export const UseAppContext = () => {
  return useContext(AppContext);
};

export const AppContextProvider = (props) => {
  const [apiData, setApiData] = useState([]);
  const globalValue = "Global Value"

  // Assign React state and constants to context object
  const AppContextObject = {
    apiValue:{
          apidata, setApiData
    },
    global:{
          globalValue  
    } 
  };
  return (
    <AppContext.Provider value={AppContextObject}>
      {props.children}
    </AppContext.Provider>
  );
};

AppContextProvider.propTypes = {
  children: PropTypes.element,
};

Integrating Context provider in index.js

Once the Context Provider is defined, it is now time to integrate it in index.js. The imported Context Provider is wrapped around the main App component. It is important to note that the context values are accessible inside the child component enclosed by the Context Provider, Any component outside the Context Provider will not be able to access the context values.

import React from 'react';
import App from './src/app';
import { AppContextProvider } from './src/context/AppContextProvider';

const AppContainer = () => {
  return (
    <AppContextProvider>
      <App />
    </AppContextProvider >
  );
};

export default AppContainer;

Accessing Context object from Child components

The context object values are accessible from Child Components through UseAppContext function from AppContextProvider File. There are two reasons to access context value, first would be to render the values in the component. The second reason is to assign values for other context values which will be rendered by other components.

In the below example, setApiData is used to assign state values to apiData. The response returned from fetchData is passed to setApiData. Now every child component will be able to access API the response through apiData without having to call fetchData

import from Context Provider 
import React, {useEffect} from 'react';
import { UseAppContext } from './AppContextProvider';

import { fetchData } from './Api';

const ChildComponent = () => {
  // Destructure values from context object
  const {
    global:{
          globalValue  
    },
    apiValue:{
          apidata, setApiData
    }
  } = UseAppContext();
 
  // Set context values from API response
  useEffect(()=>{
   fetchData.then((response)=>{
     setApiData(response);
   });
  },[]);

  return (
    <div>{globalValue}</div>
  );
};

export default ChildComponent;

Conclusion

To conclude React Context is very useful when a single instance of value is required over multiple levels of components. Hence it can be used as an alternative for Redux, However it is important to know that context cannot fully replace Redux and has several disadvantages such as all components are re-render every time any value is updated. Read more about redux vs UseContext from geeksforgeeks.org/whats-the-difference-between-usecontext-and-redux/.

If you planning to include React Context in a large-scale product, additional steps have to be taken to ensure that React Context is implemented efficiently. Learn more about using React context effectively from kentcdodds.com/how-to-use-react-context-effectively.

References