我正在尝试使用React Hooks在材料表中编辑/删除一行。尽管我可以看到状态正在修改,但它不会重新渲染材料表。使用效应在setData之后没有发射。
import React, { useState, useEffect } from "react";
import faker from "faker";
import MaterialTable from "material-table";
import * as _ from "lodash";
let testData = [];
for (var i = 0; i < 100; i++) {
testData.push({
_id: i,
fullName: faker.name.findName(),
"email.address": faker.internet.email(),
phone_number: faker.phone.phoneNumber(),
address: {
city: faker.address.city(),
state: faker.address.state(),
country: faker.address.country()
}
});
}
let columndata = [
{ title: "Id", field: "_id" },
{ title: "Name", field: "fullName" },
{ title: "Email", field: "email.address" },
{ title: "Phone", field: "phone_number" },
{ title: "City", field: "address.city" },
{ title: "State", field: "address.state" },
{ title: "Country", field: "address.country" }
];
const MyDataGrid = () => {
let [data, setData] = useState(testData);
useEffect(() => {
debugger;
if (data.length < 100) {
console.log(data.length);
}
}, [data]);
return (
<MaterialTable
columns={columndata}
data={data}
title="test-table"
options={{
filtering: true,
sorting: true,
exportButton: true,
grouping: true
}}
editable={{
onRowDelete: oldData =>
new Promise((resolve, reject) => {
setTimeout(() => {
let newData = data;
_.remove(newData, { _id: oldData._id });
debugger;
setData(newData);
resolve();
}, 1000);
})
}}
/>
// <button onClick={() => setData(_.remove(data, row => row._id !== 3))}>
// Click me
// </button>
);
};
export default MyDataGrid;
上面的代码最初使得正常。但是,当我尝试删除行时,数据已删除了一行,但是使用效应不会触发,并且不使用新数据来渲染可实质性的组件。但是,如果我使用注释的代码,则使用效果在删除后会很好地触发。我想念什么?
您不应突变数据以触发使用效果钩或与Props和Props一起工作,并且通常在React中的状态。问题是,您将相同的对象设置为状态钩,只是突变。对象引用是相同的,并且使用效率将假定没有任何变化。这样写:
new Promise((resolve, reject) => {
setTimeout(() => {
setData(data.filter(row => row._id !== oldData ._id);
resolve();
}, 1000);
})
过滤器将返回一个新数组,但所选项目将被删除。现在数据是一个新数组,这将触发使用效果挂钩,因为旧对象的引用不同。
_。删除(数据,行=> row._id!== 3((还返回一个新数组,例如更新挂钩不可变的滤镜。这将触发使用效果挂钩并引起Rerender。希望这可以帮助。快乐的编码。