How to Work with React Context API

How to Work with React Context API

Context API allows us to manage the state easily in React App. What do I mean by that? Before I explain how to work with React Context API, I want to start with working on a simple application. When we face a problem, we can see the power of context API.

Let's say, we are building a fruits store website with React. All we need to do is display the list of fruits and prices. Here is what I would do.

Create a simple example

1. Create FruitsList.js component
import React from 'react';
import FruitItem from './FruitItem';

const FruitsList = () => {
    const fruits = [
        { id: 1, name: 'apple 🍎', price: 3 },
        { id: 2, name: 'banana 🍌', price: 2.5 },
        { id: 3, name: 'orange 🍊', price: 4 },
    ];
    return (
        <ul>
            {fruits.map((fruit) => (
                <li key={fruit.id}>
                    <FruitItem fruit={fruit} key={fruit.id} />
                </li>
            ))}
        </ul>
    );
};

export default FruitsList;
2. Create FruitItem.js component
import React from 'react';

const FruitItem = ({ fruit }) => {
    return (
        <div className='fruit'>
            <h3>{fruit.name}</h3> <span>${fruit.price}</span>
        </div>
    );
};

export default FruitItem;
3. Import components into App.js
import React from 'react';
import FruitsList from './FruitsList';
import Navbar from './Navbar';
import './App.css';

const App = () => {
    return (
        <div>
            <Navbar />
            <FruitsList />
        </div>
    );
};

export default App;

Here is what it looks like (I added some simple CSS for convenience)

image.png

Why Do We Need the Context API

Now, we want to improve our website. We want to display the number of fruits the store has on Navbar. How can we solve this problem?

Well, we can move our fruits data to App.js file and pass the data to Navbar Component. However, it makes the App.js file look complicating and it will be getting worse when our app is getting bigger and more complicating.

In this case, Context API can help to solve the issue.

How to implement Context API

1. Create FruitContext.js file
  • Don forget to import useState, useContext
  • Create FruitContext with createContext();
  • Create FruitProvider
  • Move data we want to use for diffirent component into the file
  • Pass them as a value prop of Provider

FruitContext.js

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

export const FruitContext = createContext();

export const FruitProvider = (props) => {
    const [fruits, setFruits] = useState([
        { id: 1, name: 'apple 🍎', price: 3 },
        { id: 2, name: 'banana 🍌', price: 2.5 },
        { id: 3, name: 'orange 🍊', price: 4 },
    ]);
    return (
        <FruitContext.Provider value={[fruits, setFruits]}>
            {props.children}
        </FruitContext.Provider>
    );
};
2. Use FruitContext in each component
  • import { FruitContext } from './FruitContext';

FruitsList.js

import React, { useContext } from 'react';
import { FruitContext } from './FruitContext';
import FruitItem from './FruitItem';

const FruitsList = () => {
    const [fruits, setFruits] = useContext(FruitContext);

    return (
        <ul>
            {fruits.map((fruit) => (
                <li key={fruit.id}>
                    <FruitItem fruit={fruit} key={fruit.id} />
                </li>
            ))}
        </ul>
    );
};

export default FruitsList;

Navbar.js

import React, { useContext } from 'react';
import { FruitContext } from './FruitContext';

const Navbar = () => {
    const [fruits, setFruits] = useContext(FruitContext);

    return (
        <nav>
            <h1>Welcome to Our Store 🍎</h1>
            <h3>{fruits.length} items are available!</h3>
        </nav>
    );
};

export default Navbar;
3. Wrap App.js component with provider
import React from 'react';
import FruitsList from './FruitsList';
import Navbar from './Navbar';
import { FruitProvider } from './FruitContext';
import './App.css';

const App = () => {
    return (
        <FruitProvider>
            <div>
                <Navbar />
                <FruitsList />
            </div>
        </FruitProvider>
    );
};

export default App;

We can get the same result, but it has more clean code and scalability.

image.png

If you need more information about it. You can check on the official document of React. Thank you for reading my posting.