未及时设置 React 异步方法 setState 变量
React async method setState variable not being set in time
当用户单击按钮时,我正在尝试 运行 3 个方法
步骤:
1:将文件推送到 IPFS,取回 link 并将其分配给状态变量
2:将link(从那个变量)添加到区块链智能合约
3: 添加一个条目到 firebase 数据库
问题是当我尝试将 IPFS link 传递给我的智能合约时它是空的,但是在方法 运行s 之后我可以看到 link 打印到安慰。
所以我猜它没有及时设置下一个方法来查看变量。
IPFS 方法:
pushToIPFS = async(e) => {
// e.preventDefault()
await ipfs.add(this.state.buffer, (err, ipfsHash) => {
console.log(err, ipfsHash)
//this.setState({IPFSlink : ipfsHash[0].hash})
console.log(ipfsHash[0].hash)
return ipfsHash[0].hash
})
}
区块链方法:
addToBlockchain = async(e) => {
//create a new key for our student
var key = this.state.StudentNumber + this.state.account[0]
key = parseInt(hash(key), 10)
this.setState({idForBlockchain: key})
console.log(key)
//get todays date
let newDate = new Date()
newDate = newDate.getTime()
var _ipfsLink = this.state.IPFSlink
var _account = this.state.account[0]
console.log(_ipfsLink)
console.log(this.state.IPFSlink)
await storehash.methods.sendDocument(_ipfsLink, newDate,
}
Firebase 方法:
createStudent = async(e) => {
//get student details from state variables & current user uid
var _uid = this.state.uid
var _studentName = this.state.StudentName
var _studentNumber = this.state.StudentNumber
var _courseCode = this.state.CourseCode
var _courseName = this.state.CourseName
var _idForBlockchain = this.state.idForBlockchain
// database.ref.students.uid.studentNumber
const db = firebase.database()
db.ref().child("students").child(_uid).child(_studentNumber).set(
{ studentName: _studentName,
courseCode: _courseCode,
courseName: _courseName,
blockchainKey: _idForBlockchain
}
);
alert("Student added")
}
点击按钮时触发的方法:
AddMyStuff = async (e) => {
e.preventDefault()
await this.pushToIPFS()
await this.addToBlockchain()
await this.createStudent()
}
这是返回的错误,所以我假设是 await 和 setState 导致了问题,我需要的变量没有被设置。
Unhandled Rejection (Error): invalid string value (arg="_ipfsLocation", coderType="string", value=null, version=4.0.27)
有人知道怎么解决吗?
您可以将 pushToIPFS 转换为承诺而不是回调,并在触发回调时解决它。
pushToIPFS = (e) => {
return new Promise((resolve, reject) => {
ipfs.add(this.state.buffer, (err, ipfsHash) => {
resolve(ipfsHash[0].hash);
})
});
}
因为它是一个承诺,您可以使用 async/await
。
AddMyStuff = async (e) => {
e.preventDefault()
const ipfsHash = await this.pushToIPFS();
//you have your ipfsHash defined, you can pass it to your other methods
}
当用户单击按钮时,我正在尝试 运行 3 个方法
步骤:
1:将文件推送到 IPFS,取回 link 并将其分配给状态变量
2:将link(从那个变量)添加到区块链智能合约
3: 添加一个条目到 firebase 数据库
问题是当我尝试将 IPFS link 传递给我的智能合约时它是空的,但是在方法 运行s 之后我可以看到 link 打印到安慰。 所以我猜它没有及时设置下一个方法来查看变量。
IPFS 方法:
pushToIPFS = async(e) => {
// e.preventDefault()
await ipfs.add(this.state.buffer, (err, ipfsHash) => {
console.log(err, ipfsHash)
//this.setState({IPFSlink : ipfsHash[0].hash})
console.log(ipfsHash[0].hash)
return ipfsHash[0].hash
})
}
区块链方法:
addToBlockchain = async(e) => {
//create a new key for our student
var key = this.state.StudentNumber + this.state.account[0]
key = parseInt(hash(key), 10)
this.setState({idForBlockchain: key})
console.log(key)
//get todays date
let newDate = new Date()
newDate = newDate.getTime()
var _ipfsLink = this.state.IPFSlink
var _account = this.state.account[0]
console.log(_ipfsLink)
console.log(this.state.IPFSlink)
await storehash.methods.sendDocument(_ipfsLink, newDate,
}
Firebase 方法:
createStudent = async(e) => {
//get student details from state variables & current user uid
var _uid = this.state.uid
var _studentName = this.state.StudentName
var _studentNumber = this.state.StudentNumber
var _courseCode = this.state.CourseCode
var _courseName = this.state.CourseName
var _idForBlockchain = this.state.idForBlockchain
// database.ref.students.uid.studentNumber
const db = firebase.database()
db.ref().child("students").child(_uid).child(_studentNumber).set(
{ studentName: _studentName,
courseCode: _courseCode,
courseName: _courseName,
blockchainKey: _idForBlockchain
}
);
alert("Student added")
}
点击按钮时触发的方法:
AddMyStuff = async (e) => {
e.preventDefault()
await this.pushToIPFS()
await this.addToBlockchain()
await this.createStudent()
}
这是返回的错误,所以我假设是 await 和 setState 导致了问题,我需要的变量没有被设置。
Unhandled Rejection (Error): invalid string value (arg="_ipfsLocation", coderType="string", value=null, version=4.0.27)
有人知道怎么解决吗?
您可以将 pushToIPFS 转换为承诺而不是回调,并在触发回调时解决它。
pushToIPFS = (e) => {
return new Promise((resolve, reject) => {
ipfs.add(this.state.buffer, (err, ipfsHash) => {
resolve(ipfsHash[0].hash);
})
});
}
因为它是一个承诺,您可以使用 async/await
。
AddMyStuff = async (e) => {
e.preventDefault()
const ipfsHash = await this.pushToIPFS();
//you have your ipfsHash defined, you can pass it to your other methods
}