在React中的setState之后调用API

时间:2019-04-11 13:17:53

标签: javascript reactjs

我有一个React组件,该组件根据选择的日期范围使用Axios进行API调用,该日期范围正在使用setState更新。我知道setState的行为是异步的,因此我使用了箭头函数方法,但是幸运的是,由于API调用失败,因此未更新组件的状态。以下是我正在使用的代码段:

class InterfaceDetailsDialog extends React.Component {
  state = {
    fromDate: null,
    toDate: null,
    isForADate: true
  };

  componentDidMount() {
    this.setState({ open: true });
  }

  handleChangeDates = (fromDte, toDte) => {
    console.log("Handle Date Change");
    console.log(fromDte);
    console.log(toDte);
    this.setState(
      {
        isForADate: false,
        fromDate: fromDte,
        toDate: toDte
      },
      () => {
        this.props.onInterfaceStats(
          this.props.data.id,
          this.state.fromDate.format("DD-MM-YYYY"),
          this.state.toDate.format("DD-MM-YYYY")
        );
      }
    );

    console.log("In Set State", this.state.fromDate, ",", this.state.toDate);
  };

  handleSubmit = event => {
    event.preventDefault();
  };

  handleShowTodaysData = () => {
    //   this.props.clearUtilizationForVxc();
    this.setState({ isForADate: true }, this.refreshData);
  };

  renderGraph() {
    if (this.state.isForADate) {
      console.log(this.props.dte);
      return <DetailedChart data={this.props.data.points} threshold="" />;
    } else {
      console.log(this.props.utilizationForInterface);
      return <DetailedChart data={this.props.utilizationForInterface} />;
    }
  }

  displayHeader() {
    return (
      <div>
        <div
          class="row"
          style={{
            fontFamily:
              "HelveticaNeue-Light, Helvetica Neue Light, Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif",
            padding: "10px",
            fontSize: "1rem",
            fontWeight: "400"
          }}
        >
          <div className="col-md-6 ">
            <div
              class="row"
              style={{
                fontFamily:
                  "HelveticaNeue-Light, Helvetica Neue Light, Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif",
                padding: "10px",
                color: "#595959"
              }}
            >
              {/* <div class="col-md-12">Megaport Name: {this.props.data.Megaport_Name}</div> */}
            </div>
            <div class="row" style={{ padding: "10px", color: "#595959" }}>
              <div class="col-md-12">
                Interface Name: {this.props.data.interface_name}
              </div>
            </div>
          </div>
          <div class="col-md-4">
            <div class="container-fluid">
              <div class="row" style={{ padding: "10px" }}>
                <div style={{ color: "#595959" }}> Choose Date Range </div>
              </div>
              <DateRangePickerWrapper setDates={this.handleChangeDates} />
            </div>
          </div>
          <div class="col-md-2">
            <div class="container-fluid">
              <div class="row" style={{ padding: "10px" }}>
                <Button
                  onClick={this.handleShowTodaysData}
                  variant="outlined"
                  color="secondary"
                >
                  Today's data
                </Button>
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  }

  displayFooter() {
    return (
      <div>
        <div
          class="container-fluid"
          style={{
            fontFamily:
              "HelveticaNeue-Light, Helvetica Neue Light, Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif",
            padding: "10px",
            fontSize: "1rem",
            fontWeight: "400"
          }}
        >
          <div class="row">
            <div class="col-md-4">
              Time period : {this.state.isForADate && this.props.dte}{" "}
              {!this.state.isForADate &&
                this.state.fromDate.format("DD-MM-YYYY")}{" "}
              {!this.state.isForADate && <label>-</label>}{" "}
              {!this.state.isForADate && this.state.toDate.format("DD-MM-YYYY")}
            </div>
            {/* <div class="col-md-4">Region: {this.props.data.region}</div> */}
            {/* <div class="col-md-4">Path: {this.props.data.path} </div> */}
          </div>
          <div class="row">
            {/* <div class="col-md-4">Provisioned Date: {this.props.data.Provisioned_Date}</div> */}
            {/* <div class="col-md-4">Provisioning Status: {this.props.data.Provisioning_Status}</div> */}
          </div>
        </div>
      </div>
    );
  }

  render() {
    return (
      <div color="#595959">
        <Dialog
          ref="dialog"
          open={this.props.dialogStatus}
          onClose={this.props.handleClose}
          aria-labelledby="alert-dialog-title"
          aria-describedby="alert-dialog-description"
          fullWidth={true}
          maxWidth={"md"}
        >
          {this.displayHeader()}

          {this.renderGraph()}

          <DialogContent>
            <DialogContentText id="alert-dialog-description">
              {this.displayFooter()}
            </DialogContentText>
          </DialogContent>
          <DialogActions>
            <Button onClick={this.props.handleClose} color="primary">
              Close
            </Button>
          </DialogActions>
        </Dialog>
      </div>
    );
  }
}

const mapStateToProps = state => {
  console.log(state.singleInterfaceStats);
  return {
    utilizationForInterface: state.singleInterfaceStats.single_interface_data
  };
};

const mapDispatchToProps = dispatch => {
  console.log("Dispatch");
  return {
    onInterfaceStats: (id, from_date, to_date) =>
      dispatch(actionCreators.interfaceStatsByID(id, from_date, to_date))
    // clearUtilizationForVxc : () =>  dispatch(actionCreators.clearUtilizationForVxc())
  };
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(InterfaceDetailsDialog);

我无法弄清楚为什么状态没有被更新。

3 个答案:

答案 0 :(得分:0)

您首先要更新State,然后只需传递$.fn.textWidth = function(){ var html_org = $(this).html(); var html_calc = '<span>' + html_org + '</span>'; $(this).html(html_calc); var width = $(this).find('span:first').width(); $(this).html(html_org); return width; }; fromDte而不是toDte和`this.state.toDte。

this.state.fromDte

我建议您通过this.setState( { isForADate: false, fromDate: fromDte, toDate: toDte }); this.props.onInterfaceStats( this.props.data.id, fromDte.format("DD-MM-YYYY"), toDte.format("DD-MM-YYYY") ); fromDte,而不使用toDte。您可以在.format('DD-MM-YY')函数中使用这种格式。

答案 1 :(得分:0)

render中,功能handleChangeDates应该是bindedthis

<DateRangePickerWrapper setDates={this.handleChangeDates} />

<DateRangePickerWrapper setDates={this.handleChangeDates.bind(this)} />

如果componentDidMount也没有更新state,则需要创建一个constructor并将componentDidMount分配给componentDidMount.bind(this)

答案 2 :(得分:0)

尝试做:

this.setState(
  {
    isForADate: false,
    fromDate: Object.assign({}, fromDte),
    toDate: Object.assign({}, toDte)
  },
...
)

代替:

  {
    isForADate: false,
    fromDate: fromDte,
    toDate: toDte
  },