- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
一个关于 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/
我知道没有数组的 useEffect() 只在第一次渲染时运行回调。 那么useEffect(()=>{},[])和没有useEffect()的区别是什么。 我的意思是: function myCom
我的场景很少,我想了解渲染和性能方面的差异。 下面显示的示例是一个简单的函数,但请考虑一个更复杂的函数以及一个异步函数。 场景 1:定义函数并在 useEffect 中调用它。 useEffect((
我需要添加一些与 React 之外的对象交互的事件处理程序(以 Google map 为例)。 在这个处理函数内部,我想访问一些可以发送给这个外部对象的状态。 如果我将状态作为依赖项传递给效果,它可以
要限制 useEffect 在第一个渲染上运行,我们可以这样做: const isFirstRun = useRef(true); useEffect (() => { if (isF
我有一个产品组件,它显示某个类别的产品。CategoryId 从路由参数中获取,然后用户可以对产品进行分页。所以有2个useEffect,一个是改变categoryId的时候,另一个是改变当前页码的时
我有一个产品组件,它显示某个类别的产品。CategoryId 从路由参数中获取,然后用户可以对产品进行分页。所以有2个useEffect,一个是改变categoryId的时候,另一个是改变当前页码的时
我的状态宽度随着窗口大小的调整而变化,showFilters作为 Prop 从true变为false。我想在卸载时删除监听器。因此,我为每个条件使用了三个 useState。那么,我可以做任何重构来在
我正在开发一个基于对象键管理字符串数组的函数。假设它看起来像这样: import React, { useState, useEffect } from "react"; import FieldCo
新的 React Hooks 功能很酷,但有时会让我感到困惑。特别是,我将此代码包装在 useEffect Hook 中: const compA = ({ num }) => { const [
我想将其转换为 useEffect钩: 代码 componentDidMount () { this.messagesRef.on('child_added', snapshot => {
这是我的代码部分。一切正常,但 eslint 给出错误。 React Hook useEffect has missing dependencies: 'dispatch' and 'getData'
当组件安装时,我需要从两个 API 端点获取数据。现在我有: useEffect(() => { dispatch(loadSomeDataOne()); }, [dispatch])
当组件安装时,我需要从两个 API 端点获取数据。现在我有: useEffect(() => { dispatch(loadSomeDataOne()); }, [dispatch])
在 React DOCs 中,关于 useEffect() 钩子(Hook),我们得到: “使用 useEffect 安排的效果不会阻止浏览器更新屏幕。” Tip Unlike componentDi
我一直试图了解何时取消订阅(useEffect 中的回调)被准确调用。 这是codepen链接:https://codepen.io/deen_john/pen/eYmNdMy 代码 : const
当对状态、效果、上下文等使用钩子(Hook)时,我这样做: import React, { useState, useEffect, useContext } from 'react'; 但是,我注意
我正在尝试像下面这样的 useEffect 示例: useEffect(async () => { try { const response = await fetch(`ht
我在我的 React 应用中构建了一个简单的点赞、书签功能。 const [liked, setLiked] = useState(); const [bookmarked, setBookmarke
我想了解为什么在代码块的底部使用 useEffect,以及它的用途。我认为它与组件生命周期和避免无限循环有关,但我无法完全理解它并全面了解这一切。如果有人能向我解释幕后发生的事情,以及 useEffe
useEffect(() => { return history.replace({ pathname: "path/A", }); }, []); useEffe
我是一名优秀的程序员,十分优秀!