简体   繁体   English

如何在 ReactJS 中处理两个要一个接一个执行的 setState 方法?

[英]How to handle two setState methods to be executed one after other in ReactJS?

I have the following handleSubmit method, which sets the state and has a call back function to dispatch an action.我有以下 handleSubmit 方法,它设置状态并有一个回调函数来调度一个动作。

handleSubmit = event => {
    event.preventDefault();
    this.setState(
      {
        passenger: {
          ...this.state.passenger,
          flightNumber: this.props.match.params.flightNumber
        }
      },
      () =>
        this.props.dispatch(passengerActions.addPassenger(this.state.passenger))
    );

I want to set all the state properties to empty after dispatching the action.我想在分派动作后将所有状态属性设置为空。 If I call setState again as follows in handleSubmit method above, I am getting some issues, mostly because of the Asynchronous behavior or setState.如果我在上面的 handleSubmit 方法中再次调用 setState,我会遇到一些问题,主要是因为异步行为或 setState。

  handleSubmit = event => {
    event.preventDefault();
    this.setState(
      {
        passenger: {
          ...this.state.passenger,
          flightNumber: this.props.match.params.flightNumber
        }
      },
      () =>
        this.props.dispatch(passengerActions.addPassenger(this.state.passenger))
    );
      this.setState(({ passenger }) => ({
        passenger: {
          ...passenger,
          flightNumber: "",
          firstName: "",
          lastName: "",
          address: "",
          dob: "",
          passportNumber: ""
        }
      }));
   };

I am new to ReactJS and JS.我是 ReactJS 和 JS 的新手。 How can I handle this?我该如何处理? Is there a way to pass another call back method?有没有办法传递另一个回调方法? Or any other way?还是有其他方式?

First off, Jayce444's point is worth noting.首先, Jayce444 的观点值得注意。 The reason for setting state is to update what the component shows.设置状态的原因是更新组件显示的内容。 You'll be showing the flight number very briefly before wiping the passenger information out entirely.在完全清除乘客信息之前,您将非常简短地显示航班号。 So I'd either not bother with the first setState , or make the second one wait until the action has been completed (which means dispatch would need to return a promise or accept a callback).所以我要么setState会第一个setState ,要么让第二个等待直到操作完成(这意味着dispatch需要返回一个 promise 或接受一个回调)。 Waiting for the action to complete would also make sense for another reason: Actions can fail.等待操作完成还有另一个原因:操作可能会失败。 Clearing the passenger information and then having the operation fail isn't likely to be ideal... :-)清除乘客信息然后使操作失败不太可能是理想的... :-)

But answering the question:但是回答这个问题:

I want to set all the state properties to empty after dispatching the action.我想在分派动作后将所有状态属性设置为空。

In your attempt, you're calling setState immediately after having called setState , without waiting for the action to be dispatched.在您的尝试中,您在调用setState后立即调用setState ,而无需等待操作被调度。 Instead, call setState within the previous setState 's completion callback, after dispatching the action:相反,在分派动作后,在前一个setState的完成回调中调用setState

handleSubmit = event => {
  event.preventDefault();
  this.setState(
    {
      passenger: {
        ...this.state.passenger,
        flightNumber: this.props.match.params.flightNumber
      }
    },
    () => {
      this.props.dispatch(passengerActions.addPassenger(this.state.passenger))
      this.setState(({ passenger }) => ({
        passenger: {
          ...passenger,
          flightNumber: "",
          firstName: "",
          lastName: "",
          address: "",
          dob: "",
          passportNumber: ""
        }
      }));
    }
  );
};

If the dispatch can fail, be sure to only call setState to clear the fields on success.如果dispatch可能失败,请确保仅在成功时调用setState来清除字段。


Side note: If the goal of the second call is to clear all the passenger fields, you don't need to spread out the previous passenger object and you don't need the callback form of setState :旁注:如果第二次调用的目标是清除所有乘客字段,则不需要展开之前的乘客对象,也不需要setState的回调形式:

this.setState({
  passenger: {
    flightNumber: "",
    firstName: "",
    lastName: "",
    address: "",
    dob: "",
    passportNumber: ""
  }
});

Side note 2: Repeating field names like that is error-prone, You might want to use a class instead:旁注 2:像这样重复字段名称容易出错,您可能想改用类:

class Passenger {
    constructor() {
        this.flightNumber = "";
        this.firstName = "";
        this.lastName = "";
        this.address = "";
        this.dob = "";
        this.passportNumber = "";
    }
}

Then:然后:

this.setState({passenger: new Passenger()});

you can do something like :您可以执行以下操作:

this.setState({yourState},()=>{
     this.setState({againUpdateState});
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM