JD Fill
JD Fill

Reputation: 402

How to only delete one item at a time in ReactJS?

I'd like to, when a user deletes on row, for only that row to be deleted. Currently that only happens sometimes. And when you have only two items left to delete, when you click on the delete button, the row's data toggles and replaces itself. It doesn't actually delete.

Link to CodeSandbox (tables are under campaigns, dev and news tabs).

Any idea what could be causing this?

MainCrud.js

import React, { useState } from "react";

import CrudIntro from "../crud/crudIntro/crudIntro";
import CrudAdd from "../crud/crudAdd/crudAdd";
import CrudTable from "../crud/crudTable/crudTable";

const MainCrud = props => {
  // Project Data
  const projectData = [
    {
      id: 1,
      name: "Skid Steer Loaders",
      description:
        "To advertise the skid steer loaders at 0% financing for 60 months.",
      date: "February 1, 2022"
    },
    {
      id: 2,
      name: "Work Gloves",
      description: "To advertise the work gloves at $15.",
      date: "February 15, 2022"
    },
    {
      id: 3,
      name: "Telehandlers",
      description: "To advertise telehandlers at 0% financing for 24 months.",
      date: "March 15, 2022"
    }
  ];

  const [projects, setProject] = useState(projectData);

  // Add Project
  const addProject = project => {
    project.id = projectData.length + 1;
    setProject([...projects, project]);
  };

  // Delete Project
  const deleteProject = id => {
    setProject(projectData.filter(project => project.id !== id));
  };

  return (
    <div>
      <section id="add">
        <CrudIntro title={props.title} subTitle={props.subTitle} />
        <CrudAdd addProject={addProject} />
      </section>
      <section id="main">
        <CrudTable projectData={projects} deleteProject={deleteProject} />
      </section>
    </div>
  );
};

export default MainCrud;

CrudAdd.js

import React, { Component } from "react";

import "../crudAdd/crud-add.scss";
import "../../button.scss";

class CrudAdd extends Component {
  state = {
    id: null,
    name: "",
    description: "",
    date: ""
  };

  handleInputChange = e => {
    let input = e.target;
    let name = e.target.name;
    let value = input.value;

    this.setState({
      [name]: value
    });
  };

  handleFormSubmit = e => {
    e.preventDefault();

    this.props.addProject({
      id: this.state.id,
      name: this.state.name,
      description: this.state.description,
      date: this.state.date
    });

    this.setState({
      // Clear values
      name: "",
      description: "",
      date: ""
    });
  };

  render() {
    return (
      <div>
        <form onSubmit={this.handleFormSubmit}>
          <input
            name="name"
            type="name"
            placeholder="Name..."
            id="name"
            value={this.state.name}
            onChange={e => this.setState({ name: e.target.value })}
            required
          />
          <input
            name="description"
            type="description"
            placeholder="Description..."
            id="description"
            value={this.state.description}
            onChange={e => this.setState({ description: e.target.value })}
            required
          />
          <input
            name="date"
            type="name"
            placeholder="Date..."
            id="date"
            value={this.state.date}
            onChange={e => this.setState({ date: e.target.value })}
            required
          />
          <button type="submit" className="btn btn-primary">
            Add Project
          </button>
        </form>
      </div>
    );
  }
}

export default CrudAdd;

CrudTable.js

import React, { Component } from "react";

import "../crudTable/crud-table.scss";

class CrudTable extends Component {
  render() {
    const props = this.props;
    return (
      <div>
        <div class="table-responsive">
          <table class="table">
            <thead>
              <tr>
                <th scope="col">Project Name</th>
                <th scope="col">Project Description</th>
                <th scope="col">Date</th>
                <th scope="col">&nbsp;</th>
              </tr>
            </thead>
            <tbody>
              {props.projectData.length > 0 ? (
                props.projectData.map(project => (
                  <tr key={project.id}>
                    <td>{project.name}</td>
                    <td>{project.description}</td>
                    <td>{project.date}</td>
                    <td>
                      <button className="btn btn-warning">Edit</button>
                      <button
                        onClick={() => props.deleteProject(project.id)}
                        className="btn btn-danger"
                      >
                        Delete
                      </button>
                    </td>
                  </tr>
                ))
              ) : (
                <tr>
                  <td>No projects found. Please add a project.</td>
                </tr>
              )}
            </tbody>
          </table>
        </div>
      </div>
    );
  }
}

export default CrudTable;

Upvotes: 1

Views: 665

Answers (1)

Paul Fitzgerald
Paul Fitzgerald

Reputation: 12129

This is because you are filtering over projectData. Update your deleteProject method to filter over your React.useState projects variable and it will work.

const deleteProject = id => {
  setProject(projects.filter(project => project.id !== id));
};

See code sandbox example here.

Upvotes: 2

Related Questions