从组件外部的函数调用反应集挂钩

时间:2019-03-05 15:27:00

标签: javascript reactjs react-hooks

我正在测试新的React Hooks,并且遇到了无法修复的行为(并且都无法理解)。基本上,我有我的功能组件,并且在其中有一个我在其中设置钩子的函数。该函数传递给渲染的Component,并使用props从最后渲染的Component调用该函数。 太糟糕了,父母的钩子也没有相应地更新!

我知道这似乎很难理解,但是我在这里https://codesandbox.io/s/vvwp33l7o5

中复制了错误

如您所见,在App组件中,我具有onResize函数,该函数应该更新counter钩子。此函数传递给ResizeObserverContainerHook组件,并在调整ResizeObseverContainerHook div的大小时从后者调用。如您所见,width函数中的heightonResize变量是正确的,但是counter钩子似乎没有更新!实际上,它永远等于1

我不知道,看来我无法从Component外部更新钩子(这就像React Stateful Component中的状态一样,但是至少我可以传递这种情况下的函数,但是它不能工作:/)。

有人知道如何使setCounter中的12个index.js起作用吗?

2 个答案:

答案 0 :(得分:2)

重新检查代码后,我发现问题是由[]中的useEffect引起的,应将其删除,但这将导致另一个问题,props.onResize将在每个帧上被调用解决使用EventListener

答案 1 :(得分:1)

另一个答案有点混乱-您在做​​什么。当它说不要从内部调用钩子时,这意味着不要有条件地或从循环内部调用实际的API,例如有条件地定义useEffectuseState

您的问题源于您传递给Observer.js中的效果的空数组,因为该数组为空,效果永远不会刷新,因此闭包是陈旧的,以至于onResize函数调用{{1}时},setState的值将始终为零的初始值。

您需要使counter依赖于某些内容,以便在组件更新时,它可以清除以前的效果并将useEffect函数的新版本附加到ResizeObserver。

我在您的沙盒中戳了一下:https://codesandbox.io/s/x9z7k245lq?fontsize=14

现在它会将计数器状态传递给Observer组件,并且每次计数器更改时效果都会运行。事实是,我还向索引添加了一些引用以跟踪高度/宽度,因此状态并不总是更新,否则它将无限循环。我想您可以将其视为onResize

需要花费一些时间来正确思考钩子。如果您想获得一篇不错的文章来阅读有关钩子的文章,并避免一些有关空数组和陈旧的闭包的陷阱,请查看以下内容:https://overreacted.io/making-setinterval-declarative-with-react-hooks/