【问题标题】:React: state's boolean flag doesn't update fast enough反应:状态的布尔标志更新不够快
【发布时间】:2025-12-11 13:35:01
【问题描述】:

我在 if 语句中使用的状态中保留了一个名为 validationPassed 的布尔标志。如果是真的,我允许 axios 请求发生。在此之前,我将 if 语句称为 doValidation(),它有很多 if 语句。如果其中一个失败,我将该布尔标志的状态设置为false。在 setState() 中,我放置了 console.log 回调,似乎布尔标志已成功设置为 false 但不是立即设置,因为 if(this.state.validationPassed) 在不应该的时候通过了。我知道 React 状态是异步的。尝试使用 prevState 参数来切换布尔值,但它不起作用。我该如何进行这项工作?也许还有另一种方法可以在没有布尔标志的情况下进行验证?

    this.state = {

        validationPassed: true
    }
}

   this.doValidation(usernameFromUser, passwordFromUser)

   if(this.state.validationPassed){

    // axios call
   }

}

doValidation = (username, password) => {

    if(username.trim().length === 0){

          this.setState( {
            validationPassed: false }, () => {console.log(this.state.validationPassed)});
    }

    if(password.trim().length === 0){

          this.setState( {
            validationPassed: false }, () => {console.log(this.state.validationPassed)});
    } 

    if(username.trim().length < 8){

        this.setState( {
            validationPassed: false }, () => {console.log(this.state.validationPassed)});
    }

    if(username.trim().length > 20){

        this.setState( {
            validationPassed: false }, () => {console.log(this.state.validationPassed)});
    }

    if(password.trim().length < 8){

        this.setState( {
            validationPassed: false }, () => {console.log(this.state.validationPassed)});
        } 

    if(new RegExp("^(?!(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.{8,}))").test(password)){

        this.setState( {
            validationPassed: false }, () => {console.log(this.state.validationPassed)});  
    }
}

【问题讨论】:

  • 这有点超出了您的问题的直接范围,但是如果您有状态执行验证检查(并在为真时进行 axios 调用),您可能希望反转逻辑并默认改为 false。这将节省您在调用组件后立即进行 axios 调用,在验证实际检查用户名和密码条件之前。
  • 如果您在每次调用之前进行验证,您是否还需要将结果保持在状态中?即使之前的失败,验证每个字段的意义何在?
  • 你是对的。我想我太专注于状态了。我现在用返回真或假的简单函数覆盖了我的验证,一切都按我的意愿工作!谢谢

标签: javascript reactjs if-statement boolean


【解决方案1】:

尝试使用

this docs的react setState

this.setState(
  (currentStateValue)=> { value: !currentStateValue }, 
  (state)=>{console.log(state)}
)

【讨论】:

    【解决方案2】:

    我建议重新编写您的验证,制作类似

    const validationPassed = this.doValidation(usernameFromUser, passwordFromUser)
    //save validationPassed into state if you need it elsewhere
    if(validationPassed){
      // axios call
    }
    
    doValidation = (username, password) => 
      username.trim().length < 21
      && username.trim().length > 7
      && password.trim().length < 21
    ...
    

    【讨论】: