useState 变量在事件回调中为空
useState variables are null in event callback
我正在开发一个与 solidity 智能合约交互的 reactjs 网络应用程序。
此智能合约发出事件,我想在我的网络应用程序中收听此事件。
这是我的反应 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 时调用回调函数。
但是有一点很奇怪:回调函数中的hook变量都是null。
我想这是一个范围问题,因为这个变量已设置并且在我的应用程序的其他地方工作正常。
有什么想法吗?
非常感谢
正如前面的答案所暗示的,问题是 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]);
...
你可以使用另一个useEffect来观察账户和合约,然后在账户变化时可以订阅和退订
useEffect(() => {
if(account && _contract){
_contract.events.MyEvent().on("data",(e) => {
});
}
return () => {
//unscubscribe here
}
}, [account, _contract])
我正在开发一个与 solidity 智能合约交互的 reactjs 网络应用程序。
此智能合约发出事件,我想在我的网络应用程序中收听此事件。
这是我的反应 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 时调用回调函数。
但是有一点很奇怪:回调函数中的hook变量都是null。 我想这是一个范围问题,因为这个变量已设置并且在我的应用程序的其他地方工作正常。
有什么想法吗?
非常感谢
正如前面的答案所暗示的,问题是 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]);
...
你可以使用另一个useEffect来观察账户和合约,然后在账户变化时可以订阅和退订
useEffect(() => {
if(account && _contract){
_contract.events.MyEvent().on("data",(e) => {
});
}
return () => {
//unscubscribe here
}
}, [account, _contract])