首页 > 解决方案 > 首次单击时反应状态未更新且组件未呈现

问题描述

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;

标签: javascriptreactjssetstate

解决方案


 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需要时间来call实现apiresolve承诺,你的当前值pumpArray=[]这就是为什么你首先得到空数组的原因。On the next click promiseis 已经resolved让你得到你的pumpedArray. 为了解决这个问题,移动pumpArray内部then


推荐阅读