如何使用 componentDidMount() 在 render() 中创建异步 return 承诺链?
How to make an asynchronous return a promise chain within render() with componentDidMount()?
我的 return 在我的渲染函数中有一个按钮调用一个函数来启动一个承诺链,结果更新一个状态变量。但是,该值未通过。
我在 componentDidMount() 上尝试了一些尝试,但没有成功
这是我的渲染函数中的按钮
<button onClick={this.addIPFSItem}
className="btn btn-info btn-sm m-1">NewFile</button>
这会调用以下函数
addIPFSItem(){
var searchAddress = "0x9Cf0dc46F259542A966032c01DD30B8D1c310e05";
const contract = require('truffle-contract')
const simpleStorage = contract(SimpleStorageContract)
simpleStorage.setProvider(this.state.web3.currentProvider)
this.state.web3.eth.getAccounts((error, accounts) => {
simpleStorage.deployed().then((instance) => {
this.simpleStorageInstance = instance
return this.simpleStorageInstance.getLength(searchAddress);
}).then((accountLength) => {
var items = []
const ipfsPrefix = "https://ipfs.io/ipfs/";
var i;
for (i = 0; i < accountLength; i++) {
var currHash = this.simpleStorageInstance.getBook(searchAddress, i,
{from: searchAddress});
var currURL = ipfsPrefix + this.currHash;
//Here I am printing the counter values, and it prints the correct
//amount
console.log('itemhash ', i)
items.push(currHash)
}
//I do not get the value of items[1] in the console, but an undefined
//promise
console.log('address URL ', items[1])
//the state of ipfsHash is not updated correctly
return this.setState({ipfsHash: items[1]});
})
})
}
本质上,我正在执行承诺链(通过连接到 web3)并检索数据。我认为根本问题是我在 render() 中调用异步函数。我不确定如何使用 componentDidMount()
解决这个问题
console.log('address URL ', items[1])
应该给出类似 address URL 0x9Cf0dc46F259542A966032c01DD30B8D1c310e05
的内容。但是,我得到的是 address URL Promise{<pending>}
。
你的this.simpleStorageInstance.getBook
是一个promise,也就是说它是异步执行的。
要获得结果,您必须使用 .then
或新语法 async/await
。使用以下函数,您的 items
数组将填充正确的数据:
You will have to put the async
keyword before your parent function name if you choose this solution
for (i = 0; i < accountLength; i++) {
items.push(await this.simpleStorageInstance.getBook(searchAddress, i, { from: searchAddress }))
}
更短的语法意味着使用您的原始帐户数组 map
而不是使用它的长度 :
const items = myAccounts.map(async () => await this.simpleStorageInstance.getBook(searchAddress, i, { from: searchAddress }))
我的 return 在我的渲染函数中有一个按钮调用一个函数来启动一个承诺链,结果更新一个状态变量。但是,该值未通过。
我在 componentDidMount() 上尝试了一些尝试,但没有成功
这是我的渲染函数中的按钮
<button onClick={this.addIPFSItem}
className="btn btn-info btn-sm m-1">NewFile</button>
这会调用以下函数
addIPFSItem(){
var searchAddress = "0x9Cf0dc46F259542A966032c01DD30B8D1c310e05";
const contract = require('truffle-contract')
const simpleStorage = contract(SimpleStorageContract)
simpleStorage.setProvider(this.state.web3.currentProvider)
this.state.web3.eth.getAccounts((error, accounts) => {
simpleStorage.deployed().then((instance) => {
this.simpleStorageInstance = instance
return this.simpleStorageInstance.getLength(searchAddress);
}).then((accountLength) => {
var items = []
const ipfsPrefix = "https://ipfs.io/ipfs/";
var i;
for (i = 0; i < accountLength; i++) {
var currHash = this.simpleStorageInstance.getBook(searchAddress, i,
{from: searchAddress});
var currURL = ipfsPrefix + this.currHash;
//Here I am printing the counter values, and it prints the correct
//amount
console.log('itemhash ', i)
items.push(currHash)
}
//I do not get the value of items[1] in the console, but an undefined
//promise
console.log('address URL ', items[1])
//the state of ipfsHash is not updated correctly
return this.setState({ipfsHash: items[1]});
})
})
}
本质上,我正在执行承诺链(通过连接到 web3)并检索数据。我认为根本问题是我在 render() 中调用异步函数。我不确定如何使用 componentDidMount()
解决这个问题console.log('address URL ', items[1])
应该给出类似 address URL 0x9Cf0dc46F259542A966032c01DD30B8D1c310e05
的内容。但是,我得到的是 address URL Promise{<pending>}
。
你的this.simpleStorageInstance.getBook
是一个promise,也就是说它是异步执行的。
要获得结果,您必须使用 .then
或新语法 async/await
。使用以下函数,您的 items
数组将填充正确的数据:
You will have to put the
async
keyword before your parent function name if you choose this solution
for (i = 0; i < accountLength; i++) {
items.push(await this.simpleStorageInstance.getBook(searchAddress, i, { from: searchAddress }))
}
更短的语法意味着使用您的原始帐户数组 map
而不是使用它的长度 :
const items = myAccounts.map(async () => await this.simpleStorageInstance.getBook(searchAddress, i, { from: searchAddress }))