我正在测试新的 React Hooks,我遇到了一个我无法修复的行为(也无法理解)。基本上,我有我的功能组件,在它里面有一个我设置 Hook 的函数。该函数被传递给渲染的组件,并使用 Prop 从最后渲染的组件调用它。 太糟糕了,父级的钩子(Hook)没有相应更新!
我知道这似乎很难理解,但我在这里重现了错误 https://codesandbox.io/s/vvwp33l7o5
如您所见,在 App
组件中,我有一个 onResize
函数,它应该更新 counter
Hook 。此函数传递给 ResizeObserverContainerHook
组件,并在 ResizeObseverContainerHook
div 调整大小时从后者调用。如您所见,onResize
函数中的width
和height
变量是正确的,但是counter
钩子(Hook)似乎不更新!事实上,它永远等于 1
。
我不知道,似乎我无法从组件外部更新钩子(Hook)(这就像 React Stateful Component 中的状态,但至少我可以像在这种情况下那样传递一个函数,但它不会工作:/)。
知道如何让 setCounter
在 index.js
的 12 处工作吗?
最佳答案
另一个答案有点困惑 - 你所做的很好。当它说不要从内部调用钩子(Hook)时,这意味着不要有条件地或从循环内调用实际的 API,例如有条件地定义 useEffect
或 useState
。
你的问题源于你在 Observer.js 中传递给效果的空数组,因为它是空的,效果永远不会刷新所以闭包是陈旧的,这样当 onResize
函数调用 setState
,counter
的值永远为初始值0。
您需要让 useEffect
依赖于某些东西,这样当组件更新时,它会清除以前的效果并将新版本的 onResize
函数附加到ResizeObserver.
我对你的沙箱进行了一番探索:https://codesandbox.io/s/x9z7k245lq?fontsize=14
它现在将计数器状态向下传递给 Observer 组件,每次计数器更改时效果都会运行。问题是我还向索引添加了一些引用来跟踪高度/宽度,因此状态不会总是更新,否则它将无限循环。我想您可以将其视为 shouldComponentUpdate
。
正确地思考钩子(Hook)需要一段时间。如果您想阅读一篇关于钩子(Hook)的好文章并避免一些关于空数组和陈旧闭包的陷阱,请查看:https://overreacted.io/making-setinterval-declarative-with-react-hooks/
关于javascript - React 从组件外部的函数调用中设置 Hook,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55006212/