Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lære Using Context in a Real-World Scenario | React Hooks and Context for State Management
React Mastery

book
Using Context in a Real-World Scenario

Let's create a blog source about the planets. We will use Context to avoid prop drilling. The app will consist of the following components: App, Filter, PlanetList, and PlanetItem. To visualize their hierarchy, please refer to the image below.

Step 1

Create the Context in the context.js file at the top level.

js
import { createContext } from "react";

const Context = createContext();

export default Context;

Step 2

Let the entire app know that we are using context. So, we need to wrap the whole app with the Context.Provider in the App.jsx file.

jsx
import React from "react";
import Context from "../context";
import Filter from "../Filter/Filter";
import PlanetList from "../PlanetList/PlanetList";

const App = () => {
return (
<Context.Provider>
<div>
<Filter />
<PlanetList />
</div>
</Context.Provider>
);
};

export default App;

Step 3

At this step, we must set the context's data (value prop for the Context.Provider component). Let's begin by rendering some data. Data is presented in the form of the array of objects:

js
const planetData = [
{
id: "3a6d44da-bbe2-4ac2-a622-7ca5f321b71c",
name: "Mercury",
weight: "3.3011 × 10^23 kg",
size: "4,879 km",
distanceFromSun: "57.9 million km",
material: "Rocky",
image:
"https://codefinity-content-media.s3.eu-west-1.amazonaws.com/code-1/react/react-hooks-%26-context/mercury.png",
existenceYears: "4.5 billion years",
},
...
{...}
];

Here's what we'll do:

Import data from the data.js file

js
import data from "../data";

Initialize the state for the planets as an empty array using the useState hook.

js
import React, { useState } from "react";
// ...
const [planets, setPlanets] = useState([]);

Use the useEffect hook to assign the imported data to the planets variable. This ensures that we have data to render.

js
import React, { useState, useEffect } from "react";
// ...
useEffect(() => {
setPlanets(data);
}, []);

Create the variable appData, representing the entire app data, which will be an object with the planets state.

js
const appData = { planets };

Assign the appData variable to the value prop of the context provider.

jsx
return (
<Context.Provider value={appData}>
<div>
<Filter />
<PlanetList />
</div>
</Context.Provider>
);

Full code of the App.jsx file after the step three.

jsx
import React, { useEffect, useState } from "react";
import Context from "../context";
import data from "../data";
import Filter from "../Filter/Filter";
import PlanetList from "../PlanetList/PlanetList";

const App = () => {
const [planets, setPlanets] = useState([]);

useEffect(() => {
setPlanets(data);
}, []);

const appData = { planets };

return (
<Context.Provider value={appData}>
<div>
<Filter />
<PlanetList />
</div>
</Context.Provider>
);
};

export default App;

Step 4

Let's take a look at the PlanetList component. Its purpose is to render a specific markup. Inside this markup, we utilize the PlanetItem component. It's worth noting that we don't pass any props or utilize context within this component since there is no need to work with data at this level.

jsx
import React from "react";
import PlanetItem from "../PlanetItem/PlanetItem";

const PlanetList = () => {
return (
<ul>
<PlanetItem />
</ul>
);
};

export default PlanetList;

Step 5

In this step, we need to access the data in order to render the information about the planets. To do this, we will follow these steps:

Import the Context from the context.js file.

js
import Context from "../context";

Use the useContext hook to retrieve the planets data from the context.

js
import React, { useContext } from "react";
// ...
const { planets } = useContext(Context);

Render the markup using the map function, which allows us to iterate over the data set in React. Apply destructuring to access all the properties of each planet object.

jsx
return (
<>
{planets.map(
({
id,
name,
weight,
size,
distanceFromSun,
material,
image,
existenceYears,
}) => (
<li key={id}>
<img src={image} alt={name} width={160} />
<div>
<h3>{name}</h3>
<p>
Weight: <span>{weight}</span>
</p>
<p>
Size: <span>{size}</span>
</p>
<p>
Distance form Sun: <span>{distanceFromSun}</span>
</p>
<p>
Material: <span>{material}</span>
</p>
<p>
Old: <span>{existenceYears}</span>
</p>
</div>
</li>
)
)}

Full code of the PlanetItem.jsx file after the step five.

jsx
import React, { useContext } from "react";
import Context from "../context";

const PlanetItem = () => {
const { planets } = useContext(Context);

return (
<>
{planets.map(
({
id,
name,
weight,
size,
distanceFromSun,
material,
image,
existenceYears,
}) => (
<li key={id}>
<img src={image} alt={name} width={160} />
<div>
<h3>{name}</h3>
<p>
Weight: <span>{weight}</span>
</p>
<p>
Size: <span>{size}</span>
</p>
<p>
Distance form Sun: <span>{distanceFromSun}</span>
</p>
<p>
Material: <span>{material}</span>
</p>
<p>

Full app code:

Please take a moment to review the entire project, paying attention to the overall functionality and structure. For now, it is suggested to focus on understanding how the data is passed and rendered in the different components. Note how the data is obtained and utilized in the child components, excluding the Filter component. The Filter component will be a challenge in the next chapter, so you can further enhance the app's functionality.

Alt var klart?

Hvordan kan vi forbedre det?

Takk for tilbakemeldingene dine!

Seksjon 3. Kapittel 11
We use cookies to make your experience better!
some-alt