**编辑:**我找到了解决方案,这是由于克布雷泽的建议,以及对桌钩如何工作的更多了解(我在YouTube上找到了这些,愚蠢地没有完全理解)。通过道具回调将currentData
发送回ParentComponent
是我从他们的回答中得到的。但是,从tableHooks
向回调传递currentData
不起作用。然后我意识到,虽然它能够访问行,但它不能访问CurrentData。将Cell: ({ row })
更改为Cell: ({ currentData, row })
成功了。
如果你正试图在自己的Reaction应用程序中解决类似的问题,这可能不是确切的答案,但我建议你理解克莱泽的答案,希望这能让你踏上前进的道路。
原问题:
几天来,我一直遇到一个问题,似乎是因为我缺乏使用Reaction和Java脚本的经验,但由于不知道问题是什么,所以很难找到解决方案。以下是一些示例代码,在某种程度上隔离了这个问题:
export const ParentComponent = () => {
const [currentData, setCurrentData] = useState([]);
const fetchCurrentData = async () => {
let fetchedCurrentData = await getFunctions.getCurrentData();
setCurrentData(fetchedCurrentData);
}
const handleButtonPress = (row) => {
console.log(currentData);
}
return (
<div>
<ChildComponent data={currentData} handleButtonPress={handleButtonPress} />
</div>
)
}
export default function ChildComponent(props) => {
const columns = useMemo(() => COLUMNS, []);
const data = useMemo(() => props.data, [props.data]);
const tableHooks = (hooks) => {
hooks.visibleColumns.push((columns) => [
...columns, {
id: "add",
Header: "Add",
Cell: ({ row }) => (
<button onClick={() => props.handleButtonPress()}>Add</button>
)
}
])
}
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow
} = useTable({
columns,
data
}, tableHooks);
return (
<div>
<table {...getTableProps()}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{
headerGroup.headers.map(column => (
<th {...column.getHeaderProps()}>{column.render('Header')}</th>
))
}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map((row, i) => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
{
row.cells.map(cell => {
return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>;
})
}
</tr>
);
})}
</tbody>
</table>
</div>
)
}
流程是这样的:
1.接收数据
1.使用setCurrentData
更新currentData
状态变量
1.重新渲染ParentComponent
1.ChildComponent
也被渲染,并通过道具接收currentData
1.此外,ChildComponent
通过道具接收函数handleButtonPress
1.ChildComponent
使用react-table
(v7.8.0)显示数据,然后通过挂钩在表中创建额外的列,每一行都有一个按钮
1.按钮设置为从道具onClick调用handleButtonPress
1.按下按钮,调用handleButtonPress
上述流程运行正常。当从ChildComponent
调用函数handleButtonPress
时,当console.log(currentData)
记录一个空数组而不是currentData
的实际状态时,就会出现该问题。在重新渲染ParentComponent
之前,我已验证currentData
已填充,并且它已成功到达ChildComponent
。
将非常感谢在这方面的一些帮助!如果我必须猜测哪里出错了,那就是通过道具传递函数handleButtonPress
可能会在设置currentData
之前发送该函数的一个版本,但就像我说的那样,我对Reaction非常缺乏经验,这只是一个猜测!
谢谢你的阅读。
1条答案
按热度按时间h5qlskok1#
有两条缺失的信息使你无法100%肯定地回答你的问题:
1.如何调用
fetchCurrentData
?1.如何使用和调用
tableHooks
?然而,即使没有这些信息,我也可以很好地告诉您问题是什么。
首先要了解的是,每次重新呈现
ParentComponent
时,您都在定义一个全新的handleButtonPress
函数。第二件要理解的事情是,在
fetchCurrentData
函数中调用setCurrentData
之后,ParentComponent
中的currentData
变量会更改Identity。这意味着,与第一次相比,第二次重新渲染ParentComponent
时,它实际上是一个完全不同的变量。第三件要理解的事情是,
handleButtonPress
函数在currentData
变量周围形成一个闭包。但是,由于currentData
的身份在两次重新呈现之间会发生变化,因此要关闭的变量实际上是不同的。换句话说,第一次重新呈现的handleButtonPress
函数关闭了第一次重新呈现的currentData
变量,该变量被固定为[]
。第二次重新渲染的handleButtonPress
函数关闭了第二次重新渲染的currentData
变量,该变量包含您的实际数据。最后,我怀疑
tableHooks
在第一次呈现ChildComponent
期间只被调用一次,props.handleButtonPress
函数是第一个handleButtonPress
函数,它与第一个currentData
函数[]
一起使用。解决办法?
在调用
handleButtonPress
函数时,将相关数据传递给该函数。即,将函数签名更改为:顺便说一句,现在该函数是一个“纯”函数--它没有副作用(除了登录到控制台之外),它完全依赖于它的输入。您可以将要定义的函数移到呈现循环之外以获得(非常小的)性能改进,这也是声明“这确实是一个纯函数”的一种非常有用的方式。
一般来说,更喜欢纯函数,避免依赖副作用,以避免遇到像您在这里遇到的棘手情况。