javascript - 首次单击时 react 状态未更新且组件未渲染

标签 javascript reactjs setstate

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

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;

最佳答案

 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};

因此,在上面的代码中,您将在 fetch 调用之外返回 pumpArray。由于fetch需要时间调用api解决 promise ,您的pumpArray的当前值 = [] 这就是为什么你首先得到空数组的原因。在下一次单击时,promise 已经已解决,因此您可以获得 pumpedArray。 为了解决此问题,请将 pumpArray 移至 then 内。

关于javascript - 首次单击时 react 状态未更新且组件未渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51002311/

相关文章:

javascript - 在文本输入框中添加html链接?

reactjs - 如何使用 Apollo 客户端进行批量突变

javascript - 在 React 中渲染状态元素

javascript - 如何在 React 中的卸载组件中设置 State

javascript - 对于无法正常工作的复杂场景,用 useEffect Hook 替换 React Hook 中的 setState 回调

javascript - ng-repeat 显示项目的项目

javascript - 从 VKontakte 中的 javascript API 获取电子邮件

javascript - 获取 parent 深度最大的 child

javascript - react Hook 错误 : Hooks can only be called inside the body of a function component

image - 失败时重新加载缓存的网络图像