如何在react useEffect中使用solidity事件?

问题描述 投票:0回答:1

我想订阅 Solidity 事件监听器,但在渲染期间 useEffect 调用了两次。如何取消订阅活动或如何处理?

useEffect(() => {
  console.log('ADD');

  counterContract.events.Increment().on('data', (event) => ReadContractValue());
  counterContract.events.Decrement().on('data', (event) => ReadContractValue());
  return () => {
    console.log('REMOVE');
    counterContract.events.Decrement().unsubscribe();
    counterContract.events.Increment().removeAllListeners();
  };
}, []);

它写道:

ADD
REMOVE
ADD

但是两个事件监听器仍然被订阅。

next.js solidity web3js
1个回答
0
投票

您应该在调用

.on()
之前获取订阅对象,因为该对象包含卸载组件时需要调用的
unsubscribe
函数:

const isSubscribedRef = useRef(false);

useEffect(() => {
  if (isSubscribedRef.current) return;

  isSubscribedRef.current = true;

  const incrementSubscription = counterContract.events.Increment();
  const decrementSubscription = counterContract.events.Decrement();

  incrementSubscription.on('data', (event) => ReadContractValue());
  decrementSubscription.on('data', (event) => ReadContractValue());

  return () => {
    incrementSubscription.unsubscribe();
    decrementSubscription.unsubscribe();
  };
}, []);

请参阅 Web3.js 文档中的掌握事件订阅

另一方面,如果您在开发模式下使用 React 18 和

useEffect()
,您
React.StrictMode
可能会运行两次,因为它会挂载您的组件两次,如 React 18 升级帖子中所述。

我添加了

ref
来防止这种情况发生,但您不应该使用/需要它,因为您的组件在重新安装后应该按预期工作。

© www.soinside.com 2019 - 2024. All rights reserved.