【问题标题】:React state not updating in app but I can console.log correct updated state反应状态未在应用程序中更新,但我可以 console.log 更正更新状态
【发布时间】:2017-11-09 02:17:06
【问题描述】:

我有一个使用 es6 类创建的表单。表单是有状态的,并在 onChange 上更新其状态。表单状态中的信息被传递到应用组件 onSubmit。我可以通过在我的表单和应用程序组件的方法中传递的状态来控制台记录每一步,并且它的行为符合预期。在这个代码示例中,我在 app 中设置状态后有控制台,它会按照我的预期注销状态对象并添加输入值。

问题是当我查看 react 开发者工具时,状态没有更新。另外,如果我将控制台语句移动到 setState 方法中的回调函数中,它不会记录任何内容。

我的问题是如何解决这个问题,更重要的是,当应用程序中的状态似乎没有实际更新时,为什么我能够使用我正在寻找的值注销状态?

class App extends Component {
  constructor (props) {
    super(props)
    this.state = {
      appointments: [{title:'first appointment'}]
    };
    this.updateAppointments = this.updateAppointments.bind(this);
  }

  updateAppointments(newAppointment) {
    var newAppointmentList = this.state.appointments;
    newAppointmentList.push(newAppointment);
    this.setState= {
      appointments: newAppointmentList,
      //This console logs nothing
      function() {
        console.log(this.state.appointments);
      }
    }; 
    //This console logs out the state as expected with the new appointment 
    //added even thought the state in the app does not appear to have the 
    //appointment added when I look in the react dev tools  
    console.log(this.state.appointments);  
  }

  render() {
    return (
      <div className="App">
        <AppointmentForm addAppointment = {this.updateAppointments} />        
      </div>
    );
  }
}

class AppointmentForm extends Component {
  constructor (props) {
    super(props)
    this.state = {
      appointmentTitle: ''
    };
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleTitleChange = this.handleTitleChange.bind(this);
  }
  handleTitleChange(event) {
    this.setState({appointmentTitle: event.target.value});
  }
  handleSubmit(e) {
    let newAppointment = {
      title: this.state.appointmentTitle
    }
    e.preventDefault();
    this.props.addAppointment(newAppointment);
  } 
  render() {
    return (
      <div>          
          <form onSubmit={this.handleSubmit}>
            <FormGroup controlId="appointmentTitle">
              <ControlLabel>Appointment Title</ControlLabel>
              <FormControl type="text" placeholder="Appointment Title" value={this.state.appointmentTitle}
              onChange={this.handleTitleChange}/>
            </FormGroup>
          </form>        
      </div>
    );
  }
}

【问题讨论】:

    标签: javascript reactjs state


    【解决方案1】:

    您以错误的方式更新状态。

    代替:

    this.setState = {
    

    这样写:

    updateAppointments(newAppointment) {
        var newAppointmentList = this.state.appointments.slice();
        newAppointmentList.push(newAppointment);
        this.setState({
            appointments: newAppointmentList, () => {
               console.log(this.state.appointments);
            }
        }) 
    }
    

    建议: 千万不要直接修改状态值,所以先用slice()创建一个state数组的副本,推送新值然后用setState更新state .

    【讨论】:

    • 谢谢!您的建议是否与使用 redux 工具逐步完成状态有关?我还没有深入研究 redux,但我觉得我已经阅读过这种情况。
    • 那是用于反应组件的,在 redux 里面你也不应该改变状态值,检查这个声明,“reducer 是“纯函数”。它们不应该有任何副作用,也不应该改变状态 — 他们必须返回修改后的副本。”查看这篇文章:medium.com/@stowball/…
    【解决方案2】:

    您有一个代码错误。您正在设置 setState 属性,而不是调用 setState 函数。改变这个:

    this.setState= {
      appointments: newAppointmentList,
      function() {
        console.log(this.state.appointments);
      }
    }; 
    

    到这里:

    this.setState({
      appointments: newAppointmentList,
      function() {
        console.log(this.state.appointments);
      }
    });
    

    【讨论】:

    • "您正在设置 setState 属性,而不是调用 setState 函数。"就像他们在文档中明确说不要做一样。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 2020-02-27
    相关资源
    最近更新 更多