不使用最新状态的反应状态
React state not using the newest state
我正在尝试实现一个删除按钮,以使用 Ant Design UI 库从模式内的 table 中删除一行。但是,每当我调用 remove 函数时,即使我之前在初始项目之上添加了几个新项目,removeItem
组件内的 data
状态用法也不会更新,并且始终使用初始版本.每当我从 removeItem
组件内部输出 data
状态时,它总是从头开始显示 3 个项目。
但奇怪的是,如果我从 addItem
组件或 useEffect
挂钩中输出 data
内容,它会显示添加的新行。我无法弄清楚问题出在哪里。
编辑:link 到 codesandbox(编辑 barang -> 添加一些新项目 -> 删除新项目 -> 查看控制台日志)https://codesandbox.io/embed/wispy-meadow-czv6p?file=/src/App.js&codemirror=1
import { useState, useEffect } from "react";
const ModalBarang = (props) => {
const dataSource = [
{
key: 1,
code: "A123",
name: "Barang 1",
desc: "Description 1",
qty: 30,
price: 10000,
total: 30 * 10000,
},
{
key: 2,
code: "B123",
name: "Barang 2",
desc: "Description 2",
qty: 10,
price: 20000,
total: 10 * 20000,
},
{
key: 3,
code: "B123",
name: "Barang 2",
desc: "Description 2",
qty: 10,
price: 20000,
total: 10 * 20000,
},
];
const tableColumns = [
{
title: "No",
dataIndex: "key",
},
{
title: "Kode Barang",
dataIndex: "code",
render: (text, _) => {
return <Input value={text} />;
},
},
{
title: "Nama Barang",
dataIndex: "name",
render: (text, _) => {
return <Input value={text} />;
},
},
{
title: "Deskripsi",
dataIndex: "desc",
render: (text, _) => {
return <Input value={text} />;
},
},
{
title: "Qty",
dataIndex: "qty",
render: (text, _) => {
return <Input value={text} />;
},
},
{
title: "Harga",
dataIndex: "price",
render: (text, _) => {
return <Input value={text} />;
},
},
{
title: "Total",
dataIndex: "total",
},
{
title: "Hapus",
dataIndex: "remove",
render: (_, record) => {
return (
<Button
type="default"
danger="true"
onClick={() => removeItem(record.key)}
>
Hapus Barang
</Button>
);
},
},
];
const [columns, setColumns] = useState(tableColumns);
const [data, setData] = useState(dataSource);
const addItem = () => {
const newRow = {
key: data.length + 1,
code: "",
name: "",
desc: "",
qty: 0,
price: 0,
total: 0,
};
const newData = [...data, newRow];
setData(newData);
};
const removeItem = (key) => {
console.log(data); // ----> even after adding several items (addItem) the log only shows the initial values just like in datasource. E.g. initial items = 3, addItems 2 times so there should be 5 items. But when trying to remove item using this component, this console log only outputs the 3 initial items.
const newItems = data.filter((item) => item.key !== key);
setData(newItems);
};
return (
<Modal
title="Barang"
visible={props.visible}
onOk={props.onOk}
onCancel={props.onCancel}
>
<Table dataSource={data} columns={columns} pagination={{ pageSize: 5 }} />
<Button type="primary" htmlType="button" onClick={addItem}>
Tambah Barang
</Button>
</Modal>
);
};
export default ModalBarang;
当您更改对象时,React 不理解您应该这样做的更改:
setData([...newItems]);
您可以使用 ES6 扩展运算符克隆旧数组,从而生成新数组,如下所示
setData([...newItems])
这两种方法的区别在于调用它们的范围。当您使用复杂的 tablet 组件时,也许您应该参考您的库文档,因为 table 中的组件似乎以某种方式缓存。在不知道该组件如何工作的情况下,您可以将按钮更改为:
<Button
type="default"
danger="true"
onClick={() => setItemToRemove(record.key) }
>
Hapus Barang
</Button>
然后你可以在你的父组件中做这样的事情:
const [itemToRemove, setItemToRemove] = useState();
useEffect(() => {
console.log(data)
console.log(itemToRemove)}
// ...
, [itemToRemove])
让我们尝试这样的事情:
const removeItem = (key) => {
setData(prevData => prevData.filter(item => item.key !== key));
};
我正在尝试实现一个删除按钮,以使用 Ant Design UI 库从模式内的 table 中删除一行。但是,每当我调用 remove 函数时,即使我之前在初始项目之上添加了几个新项目,removeItem
组件内的 data
状态用法也不会更新,并且始终使用初始版本.每当我从 removeItem
组件内部输出 data
状态时,它总是从头开始显示 3 个项目。
但奇怪的是,如果我从 addItem
组件或 useEffect
挂钩中输出 data
内容,它会显示添加的新行。我无法弄清楚问题出在哪里。
编辑:link 到 codesandbox(编辑 barang -> 添加一些新项目 -> 删除新项目 -> 查看控制台日志)https://codesandbox.io/embed/wispy-meadow-czv6p?file=/src/App.js&codemirror=1
import { useState, useEffect } from "react";
const ModalBarang = (props) => {
const dataSource = [
{
key: 1,
code: "A123",
name: "Barang 1",
desc: "Description 1",
qty: 30,
price: 10000,
total: 30 * 10000,
},
{
key: 2,
code: "B123",
name: "Barang 2",
desc: "Description 2",
qty: 10,
price: 20000,
total: 10 * 20000,
},
{
key: 3,
code: "B123",
name: "Barang 2",
desc: "Description 2",
qty: 10,
price: 20000,
total: 10 * 20000,
},
];
const tableColumns = [
{
title: "No",
dataIndex: "key",
},
{
title: "Kode Barang",
dataIndex: "code",
render: (text, _) => {
return <Input value={text} />;
},
},
{
title: "Nama Barang",
dataIndex: "name",
render: (text, _) => {
return <Input value={text} />;
},
},
{
title: "Deskripsi",
dataIndex: "desc",
render: (text, _) => {
return <Input value={text} />;
},
},
{
title: "Qty",
dataIndex: "qty",
render: (text, _) => {
return <Input value={text} />;
},
},
{
title: "Harga",
dataIndex: "price",
render: (text, _) => {
return <Input value={text} />;
},
},
{
title: "Total",
dataIndex: "total",
},
{
title: "Hapus",
dataIndex: "remove",
render: (_, record) => {
return (
<Button
type="default"
danger="true"
onClick={() => removeItem(record.key)}
>
Hapus Barang
</Button>
);
},
},
];
const [columns, setColumns] = useState(tableColumns);
const [data, setData] = useState(dataSource);
const addItem = () => {
const newRow = {
key: data.length + 1,
code: "",
name: "",
desc: "",
qty: 0,
price: 0,
total: 0,
};
const newData = [...data, newRow];
setData(newData);
};
const removeItem = (key) => {
console.log(data); // ----> even after adding several items (addItem) the log only shows the initial values just like in datasource. E.g. initial items = 3, addItems 2 times so there should be 5 items. But when trying to remove item using this component, this console log only outputs the 3 initial items.
const newItems = data.filter((item) => item.key !== key);
setData(newItems);
};
return (
<Modal
title="Barang"
visible={props.visible}
onOk={props.onOk}
onCancel={props.onCancel}
>
<Table dataSource={data} columns={columns} pagination={{ pageSize: 5 }} />
<Button type="primary" htmlType="button" onClick={addItem}>
Tambah Barang
</Button>
</Modal>
);
};
export default ModalBarang;
当您更改对象时,React 不理解您应该这样做的更改:
setData([...newItems]);
您可以使用 ES6 扩展运算符克隆旧数组,从而生成新数组,如下所示
setData([...newItems])
这两种方法的区别在于调用它们的范围。当您使用复杂的 tablet 组件时,也许您应该参考您的库文档,因为 table 中的组件似乎以某种方式缓存。在不知道该组件如何工作的情况下,您可以将按钮更改为:
<Button
type="default"
danger="true"
onClick={() => setItemToRemove(record.key) }
>
Hapus Barang
</Button>
然后你可以在你的父组件中做这样的事情:
const [itemToRemove, setItemToRemove] = useState();
useEffect(() => {
console.log(data)
console.log(itemToRemove)}
// ...
, [itemToRemove])
让我们尝试这样的事情:
const removeItem = (key) => {
setData(prevData => prevData.filter(item => item.key !== key));
};