Reactjs 未及时设置React async method setState变量

Reactjs 未及时设置React async method setState变量,reactjs,asynchronous,solidity,ipfs,Reactjs,Asynchronous,Solidity,Ipfs,当用户点击一个按钮时,我试着依次运行3个方法 步骤: 1:将文件推送到IPFS,获取链接并将其分配给状态变量 2:将该链接(从该var)添加到区块链智能合约 3:向firebase数据库添加条目 问题是,当我尝试将IPFS链接传递到智能合约时,IPFS链接为null,但是在方法运行后,我可以看到链接打印到控制台。 所以我猜它没有及时设置,以便下一个方法看到变量 IPFS方法: pushToIPFS = async(e) => { // e.preventDefault()

当用户点击一个按钮时,我试着依次运行3个方法

步骤:

1:将文件推送到IPFS,获取链接并将其分配给状态变量

2:将该链接(从该var)添加到区块链智能合约

3:向firebase数据库添加条目

问题是,当我尝试将IPFS链接传递到智能合约时,IPFS链接为null,但是在方法运行后,我可以看到链接打印到控制台。 所以我猜它没有及时设置,以便下一个方法看到变量

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()
    }
这是返回的错误,因此我假设wait和setState导致了问题,并且没有设置我需要的变量

未处理的拒绝(错误):无效的字符串值(arg=“\u 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
    }

您可以将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
    }

ipfs.add
正在接受回调,而不是返回承诺。没有什么可等待的了对不起,我对这个有点陌生。既然没有承诺,那么等待就不需要了吗?如果你想在setState运行后做某事,只需给它一个回调作为第二个参数。给哪个方法一个回调?
ipfs.add
正在接受回调,它不会返回承诺。没有什么可等待的了对不起,我对这个有点陌生。既然没有承诺,那么等待就不需要了吗?如果你想在setState运行后做某事,只需给它一个回调作为第二个参数。给哪个方法一个回调?