React 从组件外部的函数调用中设置 Hook

React set Hook from function call outside Component

我正在测试新的 React Hooks,我遇到了一个我无法修复的行为(也无法理解)。基本上,我有我的功能组件,在它里面有一个我设置挂钩的函数。该函数被传递给渲染的组件,并使用道具从最后渲染的组件调用它。 可惜父级的钩子没有相应更新!

我知道这似乎很难理解,但我已在此处重现错误 https://codesandbox.io/s/vvwp33l7o5

如您所见,在 App 组件中我有 onResize 函数,它应该更新 counter 挂钩。此函数传递给 ResizeObserverContainerHook 组件,并在调整 ResizeObseverContainerHook div 大小时从后者调用。可以看到,onResize函数中的widthheight变量是正确的,但是counterhook好像没有更新!事实上,它永远等于 1

我不知道,似乎我无法从组件外部更新钩子(这就像 React 有状态组件中的状态,但至少我可以像在这种情况下传递一个函数,但它没有没用 :/ ).

知道如何让 setCounter 达到 index.js 中的 12 个效果吗?

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

你的问题源于你在 Observer.js 中传递给效果的空数组,因为它是空的,效果永远不会刷新,所以闭包是陈旧的,以至于当 onResize 函数调用时setStatecounter值永远为初始值零。

您需要让 useEffect 依赖于某些东西,以便当组件更新时,它会清除以前的效果并将新版本的 onResize 函数附加到 ResizeObserver。

我对你的沙箱进行了一番探索:https://codesandbox.io/s/x9z7k245lq?fontsize=14

它现在将计数器状态向下传递给 Observer 组件,每次计数器更改时效果都会 运行。问题是我还向索引添加了一些引用来跟踪 height/width 所以状态并不总是更新,否则它将无限循环。我想您可以将其视为 shouldComponentUpdate.

正确地思考钩子需要一段时间。如果您想阅读一篇关于钩子的好文章并避免一些关于空数组和陈旧闭包的陷阱,请查看:https://overreacted.io/making-setinterval-declarative-with-react-hooks/