我试图在功能组件的useEffect挂钩中使用rxjs。
我相信useEffect可以像componentDidMount和componentDidUpdate一样使用。
const Counter = () => {
const [state, setState] = useState({counter: 0});
useEffect(() => {
subscriber.subscribe((value) => {
let { counter } = state;
counter += value;
setState({ counter });
});
});
return (
<div>
<span>Counter: {state.counter}</span>
<Crementer />
</div>
);
订阅者是一个简单的rxjs主题
const subscriber = new BehaviorSubject(0);
还有一个增加/减少计数器的组件
const Crementer = () => {
return(
<>
<button onClick={() => subscriber.next(1)}>+</button>
<button onClick={() => subscriber.next(-1)}>-</button>
</>
)
};
(我也尝试过counterService.send(1))
问题是我单击+或-计数器就会连续递增或递减。
您可以在此处查看行为:https://stackblitz.com/edit/react-9auz4d
也许是因为useEffect也在更新时运行?它将可能在具有componentDidMount()的类组件中工作?
答案 0 :(得分:1)
每次更新都会调用钩子:https://reactjs.org/docs/hooks-effect.html#explanation-why-effects-run-on-each-update
因此,您可以存储由subscribe
调用返回的订阅,然后将其保留在另一个useState
中。对于每个效果调用,您只需检查是否已设置。顺便说一句,您还应该从该效果返回一个拆解函数,以便在那里也需要订阅。
或者最终,您可以使用useEffect
的第二个参数仅运行一次(How to call loading function with React useEffect only once):
useEffect(() => {
const subscription = observable.subscribe((value) => {
let { counter } = state;
counter += value;
setState({ counter });
});
return () => subscription.unsubscribe();
}, []);