gpt4 book ai didi

javascript - 状态设置方法没有影响主对象 - ReactJS

转载 作者:行者123 更新时间:2023-12-02 23:02:35 25 4
gpt4 key购买 nike

我的项目中有三个组件,AppDataTableTable

应用将呈现一个包含表格组件的DataTable。我刚刚调用了包含 data 和 columns 属性的 DataTable。

// data sample
const tmpData = [
{
name: "Can",
age: 4,
}, {
name: "David",
age: 44,
}, {
name: "Sara",
age: 14,
}, {
name: "Hani",
age: 24,
}
]

// main columns array
const tmpColumns = [
{
title: "Name",
accessor: "name",
}, {
title: "Age",
accessor: "age",
}
]

function App() {
return (
<div className="App" style={{background: "#f0f0f0", padding: "1rem"}}>
<div>App Component:</div>

<DataTable data={tmpData} columns={tmpColumns}/>
</div>
);
}

DataTable 组件仅用于处理我的表格上的选择和过滤操作。因此,它可以操纵数据和列。表将在其中呈现,这是DataTable的代码。

function DataTable(props) {

const [data, setData] = useState(props.data)
const [columns, setColumns] = useState(props.columns)

const [selection, setSelection] = useState([])

useEffect(() => {
// add select columns after component mount
handleColumnChange()
}, [])

// listen to selection change
useEffect(() => {

// selection change log, It change on each select.
console.log(selection);
}, [selection])

function handleRowSelect(rowName) {

const keyIndex = selection.indexOf(rowName);

console.log(selection, rowName, keyIndex);

if (keyIndex === -1)
setSelection(preSelection => ([...preSelection, ...[rowName]]))
else
setSelection(preSelection => preSelection.filter(sl => sl !== rowName))

}

function handleColumnChange() {

// add select column if not added already
if (!columns.find(col => col.accessor === 'select')) {

setColumns([
...[{
title: "Select",
accessor: "select",
// this method will execute to render checkbox on Select table
Cell: function (row) {

return <input type="checkbox"
onChange={() => handleRowSelect(row.name, selection)}
checked={selection.includes(row.name)}/>
},
}],
...columns,
])
}
}

return (
<div className="DataTable" style={{background: "#e0e0e0", padding: "1rem"}}>
<div>Data Table:</div>

<Table {...{data, columns}}/>
</div>
)
}

Table 组件将呈现列和适合它们的数据。对于列数组中的每一列,我们都有一个用于访问数据的项目 (accessor) 或一个用于返回自定义数据的可执行方法 (Cell),以下是其代码。

function Table(props) {

const [data, setData] = useState(props.data)

return (
<div className="Table" style={{background: "#d5d5d5", padding: "1rem"}}>
<div>Table</div>

<table>
<tbody>
<tr>
{props.columns.map((th, key) => (
<th key={key}>{th.title}</th>
))}
</tr>

{/* generating data rows */}
{data.map((dr, key) => (
<tr key={key}>
{columns.map((col, index) => (
<td key={index}>
{
// the "Cell" method has high priority than "accessor" selector
(col.Cell && typeof col.Cell === "function") ?
col.Cell(dr) :
dr[col.accessor]
}
</td>
))}
</tr>
))}
</tbody>
</table>

</div>
)
}

正如您在上面看到的,为了处理行选择,我通过在列数组的第一个索引处添加新列来操作 DataTable 组件中的列。目前一切正常。但是,当我尝试选择一行时,选择列的调用方法无法访问我的 DataTable 组件的选择数组状态。这是我的问题!

实际上,在每次选择时,selection 数组必须更新,并且目标复选框必须选中。显然,有一个选择的副本发生了变化(或者可能没有变化)。

您还可以在CodeSandbox上查看整个项目

最佳答案

我对您的代码进行了一些修复,请在 CodeSandbox 上查看。 .

这个想法是,您不需要将列放入状态,而只需要使用选择框获取列。

我还通过实现 React.useMemo 来内存计算列,对其添加了简单的优化。仅当props.columns选择状态发生变化时才会重新计算。

希望这有帮助!快乐编码! :)

关于javascript - 状态设置方法没有影响主对象 - ReactJS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57732834/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com