React在另一个循环之前等待一个循环(和setState)完成

时间:2020-09-10 20:51:32

标签: javascript reactjs foreach state

 handleSubmit = () => {
    this.setState({ modalState: false })

    this.state.codeToClass.forEach((code, classId, map) => {
      const cr = _.find(this.state.classRoles, { id: classId })

      if (code === cr.classCode) {
        console.log('here')
        this.setState(state => ({ 
          classRoles: state.classRoles.map((cc) => {
            console.log(cc.id)
            console.log(classId)
            console.log(cc.id === classId)
            if (cc.id === classId) {
              console.log('here1')
              return {
                ...cc,
                role: 'TA',
              }
            }
            console.log('what')
            return cc
          }),
        }), ()=> console.log(this.state.classRoles)) //this is called later
        
      } else {
        NotificationManager.error('Failed to register as TA.')
      }
    })
    console.log(this.state.classRoles) //this is called first
    this.state.classRoles.forEach((c) => {
      if (c.role === '') {
        api.deleteClassUser(c.id, this.state.user.id)
      } else {
        api.postAddClass(c.id, this.state.user.id, c.role)
        console.log(c)
      }
    })

    EventEmitter.publish('currentlyEnrolled', this.state.classRoles)
  }

我正在尝试在第一个forEach完成之后运行第二个forEach,即状态已更新。但是它一直按此顺序运行。有办法解决这个问题吗?

3 个答案:

答案 0 :(得分:0)

有两个选项。

  1. 使用承诺
  2. 异步等待

我认为既然地图可以用于等待状态

const tempState = this.state.codeToclass;
await tempState.map(...

这种方式可以工作:)

答案 1 :(得分:0)

Promise是你的朋友。

// You map your operations in to Promises.
 const promises = this.state.codeToClass.map((code, classId, map) => {
   return new Promise(resolve=>{
      const cr = _.find(this.state.classRoles, { id: classId })

      if (code === cr.classCode) {
        console.log('here')
        this.setState(state => ({ 
          classRoles: state.classRoles.map((cc) => {
            console.log(cc.id)
            console.log(classId)
            console.log(cc.id === classId)
            if (cc.id === classId) {
              console.log('here1')
              return {
                ...cc,
                role: 'TA',
              }
            }
            console.log('what')
            return cc
          }),
        }), ()=> resolve()) //this is called later
        
      } else {
        NotificationManager.error('Failed to register as TA.')
      }
    })
})

// and then you wait for all of the promises

await Promise.All(promises);
// then continue to execution

答案 2 :(得分:0)

this.setState是异步操作。

您可以尝试以下操作:

handleSubmit = () => {
   //some code...
   
   this.setState(state => ({
      state.codeToClass.forEach((...args) => {
         //logic to update the state...
      });
   }), setClassRoles); //call a function after the state value has updated
   
}

setClassRoles = () => {
    this.state.classRoles.forEach((...args) => {
        //your code...
    });
    EventEmitter.publish('currentlyEnrolled', this.state.classRoles)
}
相关问题