gpt4 book ai didi

reactjs - 在 useEffect 中 react 取消订阅 RxJS 订阅

转载 作者:行者123 更新时间:2023-12-02 18:18:46 26 4
gpt4 key购买 nike

一个关于 useEffect hooks 中 RxJS 的快速问题

我注意到 React 社区在 RxJS 中使用了这种取消订阅模式:

useEffect(()=>{
const sub = interval(10).subscribe()
return ()=>sub.unsubscribe()
})

我很好奇这是否是由于约定/代码的清晰性,或者我是否忽略了什么。我想以下会更简单:

useEffect(()=> interval(10).subscribe().unsubscribe)

但是,我可能忽略了一些东西。

编辑:查看选择的答案。 “This”绑定(bind)在方法调用上,而不是订阅实例化上。结果,取消订阅失败,因为“this”对象没有引用间隔订阅,而是引用了 useEffect 回调环境。感谢两位贡献者。这是 useEffect Hook 失败的示例:codesandbox.io/s/morning-bush-7b3m6h?file=/src/App.js

最佳答案

这里是:

useEffect(()=>{
const sub = interval(10).subscribe();
return () => sub.unsubscribe();
});

可以重写为:

useEffect(()=>{
const sub = interval(10).subscribe();

function unsub(){
sub.unsubscribe();
}

return unsub;
});

需要注意的关键是您将一个函数返回给 React。 unsub 不会立即被调用,它会在组件卸载时调用。

事实上,您可以返回任意代码以供稍后运行:

useEffect(() => {
/******
* Code that gets called when
* effect is run
******/
return () => { // <- start of cleanup function
/******
* Code that gets called to
* clean up the effect later
******/
} // <- end of cleanup function
});

问题

我将重写您的解决方案,以便更清楚地讨论问题。这在语义上是等价的,我只是引入了一个中间变量。

useEffect(() => 
const sub = interval(10).subscribe();
return sub.unsubscribe;
);

问题最清楚地归结为:这些值之间有什么区别?在什么情况下(如果有的话)一个会失败而另一个不会。

sub.unsubscribe
() => sub.unsubscribe()

如果取消订阅是一个函数(未绑定(bind)到类/对象的实例,因为它不包含 this 关键字),那么两者在语义上是等价的。

问题是取消订阅实际上不是一个函数。它是订阅对象上的一个方法。因此,上面的第一个值是未定义 this 的未绑定(bind)方法。当方法尝试使用其上下文 (this) 时,JavaScript 将抛出错误。

要确保 unsubscribe 作为方法被调用,您可以这样做:

useEffect(() => {
const sub = interval(10).subscribe();
return sub.unsubscribe.bind(sub);
});

虽然看起来大致相同,但您可以通过这种方式减少一级间接。

此外,我建议在大多数情况下不要使用 bind。方法、函数、匿名 lambda 函数和包含这三者中任何一个作为值的属性在各种边缘情况下的行为都不同。

据我所知,() => a.b() 可能不必要地包装了一个函数,但不会失败。再加上 JIT 可以很好地优化 99.9% 的情况。

其中 a.b.bind(a) 将在先前绑定(bind)的方法上失败,但 100% 的时间会被优化。我不会使用 bind 除非有必要(而且很少有必要)

更新:

顺便说一句:我在这里使用函数来表示不依赖于上下文的可调用代码块(没有使用 this 关键字引用的对象)和一种表示依赖于某些上下文的可调用代码块的方法。

如果您更喜欢其他术语,那很好。边读边换词,我不会生气的,保证:)

关于reactjs - 在 useEffect 中 react 取消订阅 RxJS 订阅,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71149561/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com