Реагируйте refre sh на страницу после кнопки удаления - PullRequest
0 голосов
/ 02 апреля 2020

Функция удаления моего приложения работает нормально, однако требует, чтобы пользователь вручную обновил sh страницу после того, как пользователь нажал кнопку удаления, чтобы увидеть новый список элементов в моей базе данных. Я хотел бы автоматически обновить sh после события click. Я использую реагирующие зацепки для этого проекта. Тем не менее, я нашел одно решение, если я удалил useEffect's [], но в моем бэкэнде это показывает, что он безумно запрашивает. Я не знаю, разумно ли удалить useffect's [] ?

Вот компонент, где он выбирает данные из бэкэнда и передает реквизиты другому компоненту

 import React, { useState, useEffect } from "react";
    import axios from "axios";
    import Table from "../Table/Table";
    import "./Display.css";
    const Display = () => {
      const [state, setState] = useState({ students: [], count: "" });
      const [searchItem, setsearchItem] = useState({
        item: ""
      });

      const Search = e => {
        setsearchItem({ item: e.target.value });
      };

      useEffect(() => {
        axios
          .get("/students")
          .then(response => {
            setState({
              students: response.data.students,
              count: response.data.count
            });
          })
          .catch(function(error) {
            console.log(error);
          });
      }, []); //If I remove this square brackets, it works 
      const nameFilter = state.students.filter(list => {
        return list.name.toLowerCase().includes(searchItem.item.toLowerCase());
      });

      return (
        <div>
          <h3 align="center">Student tables</h3>
          <p align="center">Total students: {state.count}</p>
          <div className="input-body">
            <div className="row">
              <div className="input-field col s6">
                <input placeholder="search student" onChange={Search} />
              </div>
            </div>
          </div>

          <table className="table table-striped">
            <thead>
              <tr>
                <th>Name</th>
                <th>Date of birth</th>
                <th>Address</th>
                <th>Zipcode</th>
                <th>City</th>
                <th>Phone</th>
                <th>Email</th>
                <th colSpan="2">Action</th>
              </tr>
            </thead>
            {nameFilter.map((object, index) => {
              return (
                <tbody key={index}>
                  <Table obj={object} /> //In here I am passing the props to the another component.
                </tbody>
              );
            })}
          </table>
        </div>
      );
    };

    export default Display;

Это второй компонент, который получает реквизит.

import React, { useState } from "react";
import { Link } from "react-router-dom";
import axios from "axios";

const Table = props => {
  const removeData = () => {
    axios
      .delete("/students/" + props.obj.id)
      .then(console.log("Deleted"))
      .catch(err => console.log(err));
  };

  return (
    <React.Fragment>
      <tr>
        <td>{props.obj.name}</td>
        <td>{props.obj.birthday}</td>
        <td>{props.obj.address}</td>
        <td>{props.obj.zipcode}</td>
        <td>{props.obj.city}</td>
        <td>{props.obj.phone}</td>
        <td>{props.obj.email}</td>
        <td>
          <Link
            to={"/edit/" + props.obj.id}
            className="waves-effect waves-light btn"
          >
            Edit
          </Link>
        </td>
        <td>
          <button onClick={removeData} className="waves-effect red btn ">
            Remove
          </button>
        </td>
      </tr>
    </React.Fragment>
  );
};

export default Table;

Ответы [ 2 ]

0 голосов
/ 02 апреля 2020

Не уверен, что поможет, но вы всегда можете удалить элемент из текущего массива, поэтому refre sh не требуется, например, вы можете передать в качестве подпрограммы функцию, которая получает идентификатор, а затем отфильтровать массив студентов, чтобы исключить элемент, который совпадает с этим идентификатором, а затем обновляет состояние с новыми свойствами массива и счетчика, что-то вроде этого

В вашем родительском элементе:

  const Display = () => {
   const [state, setState] = useState({ students: [], count: "" });

   const deleteItem = (id) => {
    const newStudents = state.students.filter(student => student.id !== id)
    const newCount = newStudents.length;
    setState({ students: newStudents, count: newCount })
   }
  // Rest of the code
  }

Теперь передайте эту функцию вашему дочернему компоненту .

<Table obj={object} deleteItem={deleteItem} />

В дочернем компоненте просто измените метод removeData, добавив реквизит deleteItem:

  const Table = props => {
   const removeData = () => {
    axios
     .delete("/students/" + props.obj.id)
     .then(console.log("Deleted"))
     .catch(err => console.log(err));
    // Now if your request succeeds call the function to remove the item from the students state array
   props.deleteItem(props.obj.id);

   };
 // Rest of the code
 }

Я знаю, что это не отвечает на ваш вопрос, но когда вы работаете с реагировать или лучше сделать это вычисления и фильтры на стороне приложения, как в этом случае, что хотя запись была удалена из БД, мы также удалили запись из объекта состояния студента, и нет необходимости обновлять sh page.

Помните, что вы создаете одностраничное приложение, поэтому мы хотим, чтобы пользователь чувствовал себя наилучшим образом без обновления страницы для каждого действия пользователя.

0 голосов
/ 02 апреля 2020

[] в хуке useEffect - это массив зависимостей, запускающий эффект. Если вы хотите вызвать эффект (без беспощадного срабатывания), вы можете создать новую переменную, которая запустит этот эффект для запуска.

import React, { useState, useEffect } from "react";
import axios from "axios";
import Table from "../Table/Table";
import "./Display.css";

const Display = () => {
  const [state, setState] = useState({ students: [], count: "" });
  const [requestData, setRequestData] = useState(new Date());
  const [searchItem, setsearchItem] = useState({
    item: ""
  });

  const Search = e => {
    setsearchItem({ item: e.target.value });
  };

  useEffect(() => {
    axios
      .get("/students")
      .then(response => {
        setState({
          students: response.data.students,
          count: response.data.count
        });
      })
      .catch(function(error) {
        console.log(error);
      });
  }, [requestData]);

  const nameFilter = state.students.filter(list => {
    return list.name.toLowerCase().includes(searchItem.item.toLowerCase());
  });

  return (
    <div>
      <h3 align="center">Student tables</h3>
        <p align="center">Total students: {state.count}</p>
        <div className="input-body">
          <div className="row">
            <div className="input-field col s6">
              <input placeholder="search student" onChange={Search} />
            </div>
          </div>
        </div>
        <table className="table table-striped">
          <thead>
            <tr>
              <th>Name</th>
              <th>Date of birth</th>
              <th>Address</th>
              <th>Zipcode</th>
              <th>City</th>
              <th>Phone</th>
              <th>Email</th>
              <th colSpan="2">Action</th>
            </tr>
          </thead>
          {nameFilter.map((object, index) => {
            return (
              <tbody key={index}>
                <Table obj={object} setRequestData={setRequestData} />
              </tbody>
            );
          })}
        </table>
      </div>
    );
  };

export default Display;

Затем вы можете запустить его из компонента Table:

import React, { useState } from "react";
import { Link } from "react-router-dom";
import axios from "axios";

const Table = props => {
  const removeData = () => {
    axios
      .delete("/students/" + props.obj.id)
      .then(() => {
        props.setRequestData(new Date());
      })
      .catch(err => console.log(err));
  };

  return (
    <React.Fragment>
      <tr>
        <td>{props.obj.name}</td>
        <td>{props.obj.birthday}</td>
        <td>{props.obj.address}</td>
        <td>{props.obj.zipcode}</td>
        <td>{props.obj.city}</td>
        <td>{props.obj.phone}</td>
        <td>{props.obj.email}</td>
        <td>
          <Link
            to={"/edit/" + props.obj.id}
            className="waves-effect waves-light btn"
          >
            Edit
          </Link>
        </td>
        <td>
          <button onClick={removeData} className="waves-effect red btn ">
            Remove
          </button>
        </td>
      </tr>
    </React.Fragment>
  );
};

export default Table;
...