【问题标题】:editing table row creates a clone in reactjs编辑表格行在 reactjs 中创建一个克隆
【发布时间】:2022-09-26 14:35:33
【问题描述】:

您好我正在尝试在 react.js 中实现编辑操作。它现在所做的是,如果我单击编辑按钮,它会在名称和电子邮件地址字段中显示行数据。如果我提交它而不做任何更改,它会创建一个克隆。如果我提交它并进行更改,它会创建一个带有新 ID 的全新数据。 由于我是新来的反应,我试图弄清楚。需要你们的一点帮助。

这是我的代码

 import React from \"react\";
import { Dna } from \"react-loader-spinner\";
import { useState } from \"react\";
function Main() {
  // *****INITIALIZING*****

  const [tableData, setTableData] = useState([]);
  const [formInputData, setformInputData] = useState({
    id: Date.now(),
    Name: \"\",
    email: \"\"
  });

  // **********DECLARING FUNCTIONS*********

  const handleChange = (evnt) => {
    const newInput = (data) => ({
      ...data, id: Date.now(),
      [evnt.target.name]: evnt.target.value
    });
    setformInputData(newInput);
  };
  const handleSubmit = (evnt) => {
    evnt.preventDefault();
    setloading(true);
      const checkEmptyInput = !Object.values(formInputData).every((res) => res === \"\");
      if (checkEmptyInput) {
        const newData = (data) => [...data, formInputData];
        setTableData(newData);
        const emptyInput = { id: \"\", Name: \"\", email: \"\" };
        setformInputData(emptyInput);
      }
    setTimeout(() => {
      setloading(false);
    }, 1000);
  };

  const handleDelete = (event, id) => {
    event.preventDefault();
    setloading(true);
    const newTableData = tableData.filter(data => data.id !== id);
    setTableData(newTableData)
    setEditData(null);

    setTimeout(() => {
      setloading(false)

    }, 1000)
  }

  const handleEdit = (event, id) => {
    event.preventDefault();
    console.log(id);

    const editData = tableData.find((data) => data.id == id)
    console.log(editData);
    const editIndex = tableData.indexOf(editData);
    setEditData(editIndex);
    setformInputData(editData);
  }

  // ************RETURNING VALUES************

  return (
    <div className=\"container\">
      <div className=\"row\">
        <div className=\"col-sm-8\">
          <div className=\"col\">
            <input
              type=\"text\"
              onChange={handleChange}
              value={formInputData.Name}
              name=\"Name\"
              className=\"form-control\"
              placeholder=\"Name\"
            />
          </div>
          <div className=\"col\">
            <input
              type=\"email\"
              onChange={handleChange}
              value={formInputData.email}
              name=\"email\"
              className=\"form-control\"
              placeholder=\"Email Address\"
            />
          </div>
          <div className=\"col\">
            <input
              type=\"submit\"
              onClick={handleSubmit}
              className=\"btn btn-success\"
            /><br></br>
            {loading ? (
              <Dna
                visible={true}
                height=\"80\"
                width=\"80\"
                ariaLabel=\"dna-loading\"
                wrapperStyle={{}}
                wrapperClass=\"dna-wrapper\"
              />
            ) : (
              <div>
                {
                  <table className=\"table\" id=\"table\">
                    <thead>
                      <tr>
                        <th>S.N</th>
                        <th>Full Name</th>
                        <th>Email Address</th>
                        <th>Action</th>
                      </tr>
                    </thead>
                    <tbody>
                      {tableData.map((data, index) => {
                        return (
                          <tr>
                            <td>{data.id}</td>
                            <td>{data.Name}</td>
                            <td>{data.email}</td>
                            <td>
                              <button
                                value={data.id}
                                onClick={(e) => handleDelete(e, data.id)}
                                className=\"btn btn-danger\"
                              >
                                Delete
                              </button> &nbsp; <button
                                value={data.id}
                                onClick={(e) => handleEdit(e, data.id)}
                                className=\"btn btn-danger\"
                              >
                                Edit
                              </button>
                            </td>
                          </tr>
                        );
                      })}
                    </tbody>
                  </table>
                }
              </div>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}
export default Main;
  • 不确定这是否会解决它,但您是否尝试过为行提供 key 属性,例如tableData.map((data, index) =&gt; &lt;tr key={data.id}&gt; ...

标签: javascript reactjs


【解决方案1】:

首先,在handleEdit() 中,您不应该分配一个ID,因为每次您在&lt;input&gt; 中写一封新信时它都会创建一个新ID。然后,您应该在handleSubmit() 上创建它。

每次按下提交时,您都在添加一个新对象,即您将数据中的值与 formDataInput 连接起来。

const newData = (data) => [...data, formInputData];
setTableData(newData);

您需要找到该元素并修改它是否存在。然后更新表。

我重构了你的代码,所以现在它可以工作了。

const handleChange = (evnt) => {
 const newInput = (data) => ({
   ...data,
   [evnt.target.name]: evnt.target.value
 });
 setformInputData(newInput);
};

const handleSubmit = (evnt) => {
 evnt.preventDefault();
 setloading(true);
   const checkEmptyInput = !Object.values(formInputData).every((res) => res === "");

  if (checkEmptyInput) {

    if (tableData.filter(e => e.id === formInputData.id).length !== 0)
      setTableData([...tableData].map(e => e.id === formInputData.id ? formInputData : e));
    else {
      let newData = [...tableData]
      newData.push({id: Date.now(), Name: formInputData.Name, email: formInputData.email})
      setTableData(newData);
   }
    setformInputData({ id: "", Name: "", email: "" });
  }

 setTimeout(() => {
   setloading(false);
 }, 1000);
};

const handleDelete = (event, id) => {
 event.preventDefault();
 setloading(true);
 const newTableData = tableData.filter(data => data.id !== id);
 setTableData(newTableData)


 setTimeout(() => {
   setloading(false)

 }, 1000)
}

const handleEdit = (event, id) => {
  event.preventDefault();
  const editData = tableData.find((data) => data.id === id)
  setformInputData(editData);
}

最后,您将看到问题为Warning: Each child in a list should have a unique "key" prop。这很简单,你只需要写&lt;tr key={index}&gt;。我们添加索引作为键,因为它的值对于每一行都是唯一的,即每个数组元素都有一个位置,所以如果你使用索引,它将永远不会重复。

【讨论】:

    【解决方案2】:

    您当前没有从 data 中删除原始行。在您的提交处理程序中将其过滤掉:

    const handleSubmit = (evnt) => {
      // ...
      if (checkEmptyInput) {
        setTableData(data => data
          .filter(row => row.id !== formInputData.id)
          .concat(formInputData));
        const emptyInput = { id: "", Name: "", email: "" };
        setformInputData(emptyInput);
      }
      // ...
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-16
      • 1970-01-01
      • 1970-01-01
      • 2015-07-02
      • 1970-01-01
      • 2015-05-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多