useState 变量在事件回调中为空

Posted

技术标签:

【中文标题】useState 变量在事件回调中为空【英文标题】:useState variables are null in event callback 【发布时间】:2021-07-14 07:21:04 【问题描述】:

我正在开发一个与solidity 智能合约交互的reactjs Web 应用程序。

这个智能合约发出事件,我想在我的网络应用程序中监听这个事件。

这是我的反应 js 文件:

import React,  useState, useEffect  from "react";
import getWeb3 from "./getWeb3";
import Contract1 from "./contracts/Contract1.json";

const App = () => 
  // Hooked variables
  const [web3, setWeb3] = useState(null);
  const [account, setAccount] = useState(null);
  const [contract, setContract] = useState(null);

 function callback(event) 
      console.log(account);  // Problem: Every hooked variables are null here
  

  async function init() 
     const web3 = await getWeb3();
     const accounts = await web3.eth.getAccounts();
     const networkId = await web3.eth.net.getId();

     setAccount(accounts[0]);

     let deployedNetwork = Contract1.networks[networkId];
     let _contract = new web3.eth.Contract(Contract1.abi, deployedNetwork && deployedNetwork.address);
     _contract.events.MyEvent().on("data",(e) => callback(e)); 
     setContract(_contract);

     setWeb3(web3);
     ...

  ;

  useEffect(() =>  init(); , []);

  ...

在我的应用程序中一切正常。

当我的智能合约发出 MyEvent 时调用回调函数。

但是有一点很奇怪:回调函数中每个挂钩的变量都是空的。 我想这是一个范围问题,因为此变量已设置并且在我的应用程序的其他地方可以正常工作。

有什么想法吗?

非常感谢

【问题讨论】:

callback和后面使用的event_callback一样吗? callback 在哪里使用?我同意,看来您在回调中有一个陈旧的 account 状态外壳。你能分享更多callbackaccount 状态所做的事情吗? 非常抱歉,我犯了一个错误。你说得对:这与我编辑帖子的功能相同。谢谢 【参考方案1】:

你可以使用另外一个useEffect来查看账户和合约,然后你可以在账户变化时订阅和取消订阅

useEffect(() => 
   if(account && _contract)
     _contract.events.MyEvent().on("data",(e) => 
        
     ); 
   
    
   return () => 
      //unscubscribe here
   
, [account, _contract])

【讨论】:

【参考方案2】:

正如前面的答案所暗示的,问题是init 函数只执行一次,我们需要把它放在依赖数组中。为此,该函数和之前的所有函数都应包含在useCallback 中。然后 React 会知道什么时候重新运行东西并且钩子对象会被填充。

这就是它的样子:

import React,  useState, useEffect, useCallback  from "react";
...

const App = () => 
  ...

 const callback = useCallback((event) => 
      console.log(account);  // Problem: Every hooked variables are null here
  , [account])

  const init = useCallback(async () => 

     ...

  , [//The proper dependencies of this function]);

  useEffect(() =>  init(); , [init]);

  ...

【讨论】:

我不明白初始化执行一次。但是 init 订阅了一个回调。调用此回调时,将设置帐户

以上是关于useState 变量在事件回调中为空的主要内容,如果未能解决你的问题,请参考以下文章

为啥回调中的 React useState 依赖项为空?

HttpContext.Current 在异步回调中为空

useState 中的变量未在 useEffect 回调中更新

Bootbox Ajax 帖子在回调函数中为空

React-native this.props 在回调函数中为空

不能在回调中调用 React Hook “useState”