在钩子依赖性阵列中可观察到无限循环
我有一个自定义挂钩,该挂钩接收一组可观察到的参数,然后(在使用效果钩中)在可观察到的可观察到一个值时,都会设置内部状态。
export const myHook = (obs$: Observable<any>) => {
const [state, setState] = useState();
useEffect(() => {
obs$.subscribe((x) => setState(x));
}, [obs$]);
return state;
}
这会导致无限循环,我猜是因为obs $
对象的某些属性随着它的解决而在变化。它可以与一个空的依赖性数组一起使用,但是为了正确的目的,我不想这样做,因为如果obs $
确实在自定义挂钩范围之外进行了重新计算(不确定为什么会发生这种情况,但仍然如此)。
I have a custom hook which receives an array of Observables as a parameter, then (in a useEffect hook) sets internal state any time the Observable emits a value.
export const myHook = (obs$: Observable<any>) => {
const [state, setState] = useState();
useEffect(() => {
obs$.subscribe((x) => setState(x));
}, [obs$]);
return state;
}
This causes an infinite loop, I'm guessing because some property on the obs$
object is changing as it resolves. It works with an empty dependency array, but for the sake of correctness I don't want to do that because it should recalculate if obs$
is genuinely changed outside of the scope of the custom hook (not sure why this would ever happen, but still).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
观察物是对象。以下表达式为fals:
{} === {}
(类似地,==
和其他“类似”对象)(在此处提供更多信息)。React的
使用效果
挂钩使用===
比较依赖项以查看它们是否已更改。由于每个obs $
都有不同的引用,因此您需要找到一种方法来确保将相同的确切对象引用传递给钩子。如果===
比较器返回true
,则useffect
将不会再次运行。这就提出了一个问题:除非更改,否则我们如何确保
obs $
具有相同的参考?有很多方法,但是 usememo 和 usecallback 是可以帮助此帮助的工具。每个它们都有自己的依赖性,但不应在您的钩子中使用它们,因为您需要依赖相同的
obs $
与每个函数调用更改的相同问题。如果
obs $
具有退出
方法,则在组件重新租赁(或删除)时,我会退订。在React文档中,有一个类似的示例 。
Observables are objects. The following expression is false:
{} === {}
(similarly for==
and other "similar" objects) (more info here).React's
useEffect
hook uses===
to compare dependencies to see if they've changed. Since eachobs$
has different references, you'll need to find a way to ensure that the same exact object reference is passed to your hook. If the===
comparator returnstrue
, then theuseEffect
won't run again.That begs the question: How do we ensure that the
obs$
has the same reference unless it changes?There are many ways, but useMemo and useCallback are tools that can help with this. Each of those have their own dependencies, but they shouldn't be used in your hook since you'll have the same problem of needing to depend on the same
obs$
that changes with each function call.If
obs$
has anunsubscribe
method, then I would unsubscribe when the component re-renders (or unmounts).In the React docs, there is a similar example.