Displaying Data using Components and State

Displaying Data using Components and State

One key feature when building an App using React is using State to manage and control aspects of your application. State is a piece of data that will change over time. For example, if I want to use a search bar to filter data, or sort data with radio buttons. In or us to keep track of the data as it is changing, we would need to use state.

There are different ways to use State but the topic of discussing today is, how can we use state to display data. Let’s say we have an array of pizzas, and we want to display a pizza list in a component called Pizza List that contains another component called Pizza for each individual pizza.

1. Import use State and the Pizza Data:

To useState, you would need to make sure it is imported in the App component or whichever component will be using state. We also need to import the data set that we will be using from the file that is it located at.

import React, {useState} from "react";
import {PIZZAS } from "../data"

2. Initialize state in App:

To get started we need to begin by setting the initial state of our pizzas within our App component, this will be the current state of the pizzas, which should be an empty array of data.

const [pizzas, setPizzas]= useState(PIZZAS)

3. Pass the data as a Prop:

The main goal is for our Pizza component to access the data so that it can be rendered in our App. Therefore, the pizza data needs to be passed down from the App component so that the PizzaList can also pass it as a prop to the Pizza component for rendering.

import React, {useState} from "react";
import {PIZZAS} from "../data"

function App() {
return (
    <div className="App">
      <PizzaList tasks={tasks}/>
    </div>
  );
}

4. Accept the data from the Prop:

Now that we have our data passed down, we need to take in the data within the components. Console log to make sure the data stays the same and the code is working on the PizzaList component.

import React from "react";
import Task from "./Task"

 function PizzaList({tasks}) {

 }

export default PizzaList;

5. Map out the data:

On our PizzaList component, we will need to render a list of pizzas using the pizza data array. To do this we will circle back to basic JavaScript and use the .map() syntax to return a new array. Within the mapped pizza variable we will render the Pizza component for each pizza data and also pass down the data as a prop.

import React from "react";
import Pizza from "./Pizza"

function PizzaList({pizzas}) {

const mappedPizza= pizzas.map(pizza => (
  <Task pizza={pizza} key={pizza.text}/>
))
  return (
    <div className="pizzas">
  {mappedPizza}
    </div>
  );
}

export default PizzaList;

6. Destructure our Pizza component:

Moving on to the last component, once we mapped out our data, we will also need to take in the data that was passed as a prop from the PizzaList component. Then we will use the data to render our individual pizza data by destructuring the prop.

import React from "react";

function Pizza({pizza}) {
  return (
      <div className="pizza">
      <div className="label">{pizza.category}</div>
      <div className="text"> {pizza.text}</div>
      <button className="delete">X</button>
    </div>
  )
}

export default Pizza;

7. Update State with new data:

Earlier we discussed that, state is data that changes over time. Once we initialize state with our useState Hook, we can now change the data by using setState. For this example, we can use state to delete the pizza data once it has been clicked. In this case we would be changing our initial pizza data array to exclude the clicked pizza and then re-render once it is removed.

In the App component, we can start by using a call back function to filter out the deleted pizza and then setState to the new array without the pizza.

const handleDelete = (deletedPizza) => {
const filteredPizzas = pizzas.filter((pizza) => deletedPizza.text !== pizza.text)
setPizzas(filteredPizzas)
}

Since we have now defined how we want to setState, we have to initialize the handleDelete callback function and we can do that by passing it down as a prop to the Pizza component.

//App.js
<PizzaList pizzas={pizzas} handleDelete={handleDelete}/>

//PizzaList.js
function PizzaList({pizzas, handleDelete}) {
const mappedPizza= pizzas.map(pizza => (
  <Pizza pizza={pizza key={pizza.text} handleDelete={handleDelete} />
))

After the callback function is passed down to the Pizza component as a prop and accepted. We can then use the handleDelete prop to define our onClick event.

import React from "react";

function Pizza({pizza, handleDelete}) {
  const handleDeletePizza = () => {
    handleDelete(pizza)
  }

  return (
      <div className="pizza">
      <div className="label">{pizza.category}</div>
      <div className="text"> {pizza.text}</div>
      <button className="delete" onClick={handleDeletePizza}>X</button>
    </div>
  )
}

export default Pizza

When the code has been executed, you should be able to see a list of pizzas. When the pizza is clicked it should delete the clicked pizza and re-render the new array of pizzas.