Home > other >  Delete object from list in another class
Delete object from list in another class

Time:10-22

I'm learning React and have come to the problem that I do not know how I can get "access" to the "setPeople" from the List.js class.
The GUI looks as followed. GUI

I know how to handle this if I would just do all of it in one class (App.js for example). But by doing it the "clean" way, I can't get the desired solution.

I guess I have to declare the "const [people, setPeople] = useState(data) somewhere else, right?

List.js:

const List = ({ people }) => {
      const deletePerson = (id) => {
        let newPeople = people.filter((person) => person.id !== id);
        console.log(newPeople);
        // setPeople(newPeople); // ***how can I access this setPeople method in order to update the list?***
      };
      return (
        <>
          {people.map((person) => {
            const { id, name, age, image } = person;
            return (
              <article key={id} className="person">
                <img src={image} alt={name} />
                <div>
                  <h4>{name}</h4>
                  <p>{age}</p>
                  <button
                    className="btn"
                    onClick={() => {
                      deletePerson({ id });
                    }}
                  >
                    Delete me (HERE)
                  </button>
                </div>
              </article>
            );
          })}
        </>
      );
    };

App.js:

function App() {
  const [people, setPeople] = useState(data); //data is just an array of objects
  return (
    <main>
      <section className="container">
        <h3>{people.length} birthdays today</h3>
        <List people={people}></List>
        <button onClick={() => setPeople([])}>Clear all</button>
      </section>
    </main>
  );
}

CodePudding user response:

You could define a callback onDeletePerson prop on your List component:

const List = ({ people, onDeletePerson }) => {
      const deletePerson = (id) => {
        let newPeople = people.filter((person) => person.id !== id);
        console.log(newPeople);
        onDeletePerson(newPeople);
      };
  ...
};

and then, in your App component, you retrieve the callback value

function App() {
  const [people, setPeople] = useState(data); //data is just an array of objects
  const handleOnDeletePerson = (value) => {
     setPeople(value);
  };
  return (
    <main>
      <section className="container">
        <h3>{people.length} birthdays today</h3>
        <List people={people} onDeletePerson={handleOnDeletePerson}></List>
        <button onClick={() => setPeople([])}>Clear all</button>
      </section>
    </main>
  );
}

Another way would be to use a state management library such as Redux.

CodePudding user response:

You can give the List component an onDelete event handler props, it will be triggered when the user clicks the delete button.

Controls the people state in the App component, and List is more like a pure UI component, does not include business logic.

App.js:

import "./styles.css";
import { useState } from "react";
import List from "./List";

export default function App() {
  const [people, setPeople] = useState([
    { id: 1, name: "a", age: 20, image: "" },
    { id: 2, name: "b", age: 20, image: "" },
    { id: 3, name: "c", age: 20, image: "" }
  ]);
  return (
    <main>
      <section className="container">
        <h3>{people.length} birthdays today</h3>
        <List
          people={people}
          onDelete={({ id }) => {
            setPeople((pre) => pre.filter((person) => person.id !== id));
          }}
        ></List>
        <button onClick={() => setPeople([])}>Clear all</button>
      </section>
    </main>
  );
}

List.js:

import React from "react";

const List = ({ people, onDelete }) => {
  return (
    <>
      {people.map((person) => {
        const { id, name, age, image } = person;
        return (
          <article key={id} className="person">
            <img src={image} alt={name} />
            <div>
              <h4>{name}</h4>
              <p>{age}</p>
              <button
                className="btn"
                onClick={() => {
                  onDelete({ id });
                }}
              >
                Delete me (HERE)
              </button>
            </div>
          </article>
        );
      })}
    </>
  );
};

export default List;

Codesandbox

CodePudding user response:

Multiple options to achieve that

  1. Pass setPeople in props to List
  2. Use React.Context and have setPeople in the context, use React.useContext hook to access to the context in List
  3. Use global state (with Redux for example) and you can connect to the shared store in components you need, and dispatch setPeople from anywhere
  • Related