Codesandbox示例:https://codesandbox.io/s/react-table-state-not-updating-hmquq?file=/src/App.js
我正在使用react-table软件包(版本7.1.0)。
我有一个表格,其中显示了一些发票,如下所示:
用户应该可以使用selected
复选框来选择其中一些或全部项目。
selected
字段不是数据的一部分。但是,当用户单击selected
复选框时,该字段应切换,并应填充一个存储文档编号的数组。
要存储文档编号,我有一个有状态的getter和setter:
const [selectedInvoiceIds, setSelectedInvoiceIds] = useState([]);
要填充该字段,我试图简单地从复选框的onChange
不可变地将文档编号添加到数组:
{
Header: "Selected",
accessor: "selected",
Cell: item => {
const { documentNumber } = item.row.values;
return (
<input
type="checkbox"
checked={selectedInvoiceIds.includes(documentNumber)}
onChange={() => {
setSelectedInvoiceIds([...selectedInvoiceIds, documentNumber]);
}}
/>
);
}
}
首次单击复选框时,将填充selectedInvoiceIds
:
selectedInvoiceIds: ["706942"]
问题是:
checked={selectedInvoiceIds.includes(documentNumber)}
selectedInvoiceIds
值将被覆盖,就像状态被重新初始化为介于两者之间的[]
一样。 能否解释为什么发生这些状态问题以及如何解决?
我知道react-table公开的useTableState
值,但是我不知道如何将其应用于此用例。
Codesandbox示例:https://codesandbox.io/s/react-table-state-not-updating-hmquq?file=/src/App.js
答案 0 :(得分:2)
此代码中存在多个问题:
// 1) updates to state should should use callback function if it uses prv state
return (
<input
type="checkbox"
checked={selectedInvoiceIds.includes(documentNumber)}
onChange={() => {
setSelectedInvoiceIds(prvSelectedInovicesId => [...prvSelectedInovicesId, documentNumber]);
}}
/>
);
// 2) also columns is using useMemo, however not providing dependencies, so columns are not being updated when the selectedInvociesIds state gets updated
// 3) you are not yet handling the toggle, this mean you are just always just adding to the array and not removing from it
这是工作版本代码沙箱 https://codesandbox.io/s/react-table-state-not-updating-wkri3?file=/src/App.js
答案 1 :(得分:1)
由于useMemo,请将数组添加到最后一个参数
const columns = React.useMemo(
// ....
,
[selectedInvoiceIds]
);
并且由于需要选中复选框,因此将选定的id保留在对象中而不是数组中并以此更新是更合理的
setSelectedInvoices({
...selectedInovicesIds,
documentNumber: !selectedInovicesIds[documentNumber]}
)
因此它将切换标记