反应 useEffect 依赖不从异步回调触发
React useEffect dependency not triggering from async callback
我试图将其分解为最简单的组件,以理解为什么 ButtonStatus
中的 useEffect
在 eventDataId
中的状态更新时未更新的原因ButtonView
React 组件的 14=] 函数。在这个例子中,我在我的本地 Ganache 实例上调用以太坊的智能合约,它工作正常并在每次调用时返回一个新的 eventDataId。
用例:用户点击按钮,handleButtonClick
触发请求(在本例中是以太坊智能合约调用),在 on()
函数中,我们设置状态eventDataId
。我 希望 这将通过它的依赖项数组触发 ButtonStatus
useEffect
,特别是 [eventDataId]
。我认为这反过来应该查找其他信息并呈现 MintStatus
.
// I've removed all extraneous lines of code, for example the .catch() and .error() handlers on the contract.methods calls.
import React, { useEffect, useState} from 'react';
const Web3 = require('web3');
const ButtonStatus = ({contract, account}) => {
const [eventDataId, setEventDataId] = useState();
const [additionalData, setAdditionalData] = useState();
function retrieveAdditionalData(contract, account) {
contract.methods.additionalData()
.call({ from: account })
.then(function(res) {
setAdditionalData(res);
});
}
useEffect(() => {
retrieveAdditionalData(contract, account);
}, [eventDataId]);
return (
<div>Event Data Id is {eventDataId} with {additionalData}</div>
);
}
class ButtonView extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
eventDataId: undefined
};
this.handleButtonClick = this.handleButtonClick.bind(this);
}
handleButtonClick() {
const setState = this.setState.bind(this);
const contract = this.props.contract;
const account = this.props.account;
contract.methods.doSomething()
.send({ from: account })
.on('confirmation', function(confirmationNumber, receipt){
let eventDataId = receipt.events['Data Event'].returnValues.eventDataId;
setState({ eventDataId: eventDataId });
});
}
render() {
return (
<button onClick={this.handleButtonClick}>Click Me</button>
<ButtonStatus contract={this.props.contract} account={this.props.account} />
);
}
}
export default ButtonView;
我确定我在这里遗漏了一些基本概念。 React{ useState }
的幕后“工作原理”是否甚至将 ButtonView
中的 eventDataId
state
值关联到 ButtonStatus
中的 state
值.我怀疑这就是问题所在。
简而言之,我正在寻求帮助以了解 contract.methods.doSomething().on(...)
的响应如何触发 ButtonStatus
的 useEffect
。
当父 ButtonView
中的 eventDataId
状态更新时,您似乎希望 useEffect
挂钩 ButtonStatus
到 运行。当父级中的状态更新时,它将触发重新渲染,从而重新渲染子 ButtonStatus
组件。您可以将 this.state.eventDataId
作为道具传递给 useEffect
的依赖项数组。
按钮视图
render() {
return (
<button onClick={this.handleButtonClick}>Click Me</button>
<ButtonStatus
contract={this.props.contract}
account={this.props.account}
eventDataId={this.state.eventDataId}
/>
);
}
按钮状态
const ButtonStatus = ({ account, contract, eventDataId }) => {
const [additionalData, setAdditionalData] = useState();
function retrieveAdditionalData(contract, account) {
contract.methods.additionalData()
.call({ from: account })
.then(function(res) {
setAdditionalData(res);
});
}
useEffect(() => {
retrieveAdditionalData(contract, account);
}, [eventDataId]);
return (
<div>Event Data Id is {eventDataId} with {additionalData}</div>
);
}
我试图将其分解为最简单的组件,以理解为什么 ButtonStatus
中的 useEffect
在 eventDataId
中的状态更新时未更新的原因ButtonView
React 组件的 14=] 函数。在这个例子中,我在我的本地 Ganache 实例上调用以太坊的智能合约,它工作正常并在每次调用时返回一个新的 eventDataId。
用例:用户点击按钮,handleButtonClick
触发请求(在本例中是以太坊智能合约调用),在 on()
函数中,我们设置状态eventDataId
。我 希望 这将通过它的依赖项数组触发 ButtonStatus
useEffect
,特别是 [eventDataId]
。我认为这反过来应该查找其他信息并呈现 MintStatus
.
// I've removed all extraneous lines of code, for example the .catch() and .error() handlers on the contract.methods calls.
import React, { useEffect, useState} from 'react';
const Web3 = require('web3');
const ButtonStatus = ({contract, account}) => {
const [eventDataId, setEventDataId] = useState();
const [additionalData, setAdditionalData] = useState();
function retrieveAdditionalData(contract, account) {
contract.methods.additionalData()
.call({ from: account })
.then(function(res) {
setAdditionalData(res);
});
}
useEffect(() => {
retrieveAdditionalData(contract, account);
}, [eventDataId]);
return (
<div>Event Data Id is {eventDataId} with {additionalData}</div>
);
}
class ButtonView extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
eventDataId: undefined
};
this.handleButtonClick = this.handleButtonClick.bind(this);
}
handleButtonClick() {
const setState = this.setState.bind(this);
const contract = this.props.contract;
const account = this.props.account;
contract.methods.doSomething()
.send({ from: account })
.on('confirmation', function(confirmationNumber, receipt){
let eventDataId = receipt.events['Data Event'].returnValues.eventDataId;
setState({ eventDataId: eventDataId });
});
}
render() {
return (
<button onClick={this.handleButtonClick}>Click Me</button>
<ButtonStatus contract={this.props.contract} account={this.props.account} />
);
}
}
export default ButtonView;
我确定我在这里遗漏了一些基本概念。 React{ useState }
的幕后“工作原理”是否甚至将 ButtonView
中的 eventDataId
state
值关联到 ButtonStatus
中的 state
值.我怀疑这就是问题所在。
简而言之,我正在寻求帮助以了解 contract.methods.doSomething().on(...)
的响应如何触发 ButtonStatus
的 useEffect
。
当父 ButtonView
中的 eventDataId
状态更新时,您似乎希望 useEffect
挂钩 ButtonStatus
到 运行。当父级中的状态更新时,它将触发重新渲染,从而重新渲染子 ButtonStatus
组件。您可以将 this.state.eventDataId
作为道具传递给 useEffect
的依赖项数组。
按钮视图
render() {
return (
<button onClick={this.handleButtonClick}>Click Me</button>
<ButtonStatus
contract={this.props.contract}
account={this.props.account}
eventDataId={this.state.eventDataId}
/>
);
}
按钮状态
const ButtonStatus = ({ account, contract, eventDataId }) => {
const [additionalData, setAdditionalData] = useState();
function retrieveAdditionalData(contract, account) {
contract.methods.additionalData()
.call({ from: account })
.then(function(res) {
setAdditionalData(res);
});
}
useEffect(() => {
retrieveAdditionalData(contract, account);
}, [eventDataId]);
return (
<div>Event Data Id is {eventDataId} with {additionalData}</div>
);
}