第一次单击时反应状态未更新,并且未渲染组件

时间:2018-06-23 14:52:17

标签: javascript reactjs setstate

retrieveInTransit()是点击处理程序。 API调用检索数据并将对象数组返回到setState()函数中的新状态对象中。第一次单击将为pumps属性记录一个空数组。如果再次单击它,将得到填充的pumps数组。为什么我必须单击两次?即使Equipment component函数中的日志返回正确的泵阵列,也作为render()的道具传入,Equipment component不会呈现。我对此不知所措,任何帮助将不胜感激。

import React, { Component } from 'react';
import {ListGroup} from 'reactstrap';
import Equipment from './Equipment';

class Transit extends Component {
  constructor(props) {
    super(props);
    this.state = {
      pending: false,
      pumps: []
    };
  }

  handleCancelClick = (index) => {
    this.setState((prevState) =>
      prevState.pumps[index].isCancelled = !prevState.pumps[index].isCancelled
    );

    this.setState((prevState) => {
        prevState.pumps.every((equipment) => equipment.isCancelled === false)
          ? prevState.pending = false: prevState.pending = true
      }
    )};


  populate_transit = () => {
    let pumpArray = [];
    fetch('http://192.168.86.26:8000/api/v1/transit_list', {mode: 'cors'})
      .then(response => response.json())
      .then(MyJson => MyJson.map((entry) =>{
        if (document.getElementsByClassName('title')[0].innerText.toLowerCase().includes(entry.transferfrom)) {
          pumpArray.push(
            {
              unitnumber: entry.unitnumber,
              id: entry.id,
              message: entry.unitnumber + ' was moved to ' + entry.transferto,
              isCancelled: false
            });
        }}));

    return pumpArray
  };


  cancelTransit = () => {
    let cancelled = this.state.pumps.filter((movement) => movement.isCancelled);
    let cancelledId = cancelled.map((object) => object.id);
    fetch('http://192.168.86.26:8000/api/v1/transit_list/', {
      method:'POST',
      mode: 'cors',
      body: JSON.stringify(cancelledId),
      headers:{
        'Content-Type': 'application/json'
      }
        }
      );
    this.populate_transit()
  };

  retrieveInTransit = () => {
    if (this.state.pending) {
      this.setState({
        pending: false,
        pumps: this.cancelTransit()
      }, console.log(this.state))} else {
      this.setState({
        pending: false,
        pumps: this.populate_transit()
      }, console.log(this.state))
    }

  };


  render() {
    console.log(this.state.pumps);
    return (
      <ListGroup>
        <Equipment transitequipment={this.state.pumps} cancelClick={this.handleCancelClick}/>
        <button className='btn btn-dark' onClick={this.retrieveInTransit}>
          {this.state.pending ? 'Submit Cancellations': 'Refresh'}
        </button>
      </ListGroup>
    );
  }
}

export default  Transit;

1 个答案:

答案 0 :(得分:1)

 populate_transit = () => {
let pumpArray = [];
fetch('http://192.168.86.26:8000/api/v1/transit_list', {mode: 'cors'})
  .then(response => response.json())
  .then(MyJson => MyJson.map((entry) =>{
    if (document.getElementsByClassName('title')[0].innerText.toLowerCase().includes(entry.transferfrom)) {
      pumpArray.push(
        {
          unitnumber: entry.unitnumber,
          id: entry.id,
          message: entry.unitnumber + ' was moved to ' + entry.transferto,
          isCancelled: false
        });
    }}));

return pumpArray};

因此,在上面的代码中,您将在pumpArray调用之外返回fetch。由于fetch需要花费时间callapiresolve,因此pumpArray = []的当前值就是为什么首先是空数组。在next clickpromise已经resolved,因此您得到了pumpedArray。 为了解决此问题,请将pumpArray移到then内。