This question already has answers here:
Why calling react setState method doesn't mutate the state immediately?
                            
                                (6个答案)
                            
                    
                3年前关闭。
        

    

我正在处理这个FreeCodeCamp排行榜表,并且当单击突出显示的表标题时,应用程序始终都调用此url https://fcctop100.herokuapp.com/api/fccusers/top/ recent或这个https://fcctop100.herokuapp.com/api/fccusers/top/,从而在过去30天或所有时间中得分最高的露营者之间进行排序。

我的问题是,我必须单击两次才能获得所需的结果。在CamperLeaderboard时,在handleSort组件console.log函数中,状态只有在我单击两次后才改变

单击一次

handleSort = (sort) => {
  console.log(sort);  // alltime
  console.log(this.state.sort)  //recent
  this.setState({ sort: sort });
  console.log(this.state.sort)  //recent
  this.getData();
};


单击两次

handleSort = (sort) => {
  console.log(sort);  // alltime
  console.log(this.state.sort)  //alltime
  this.setState({ sort: sort });
  console.log(this.state.sort)  //alltime
  this.getData();
};


这是CodePen preview,下面是完整代码

/**
  Table body component
*/
class Table extends React.Component {
  handleSort = (e, sort) => {
    this.props.handleSort(sort);
  };

  renderCampers = (key, count) => {
    const camper = this.props.campers[key];
    return(
      <tr key={key}>
        <td>{count}</td>
        <td>
          <a href={`https://www.freecodecamp.com/${camper.username}`} target='_blank'>
            <img src={camper.img} />
            {camper.username}
          </a>
        </td>
        <td className='center'>{camper.recent}</td>
        <td className='center'>{camper.alltime}</td>
      </tr>
    )
  };

  render() {
    let count = 0;
    return (
      <div>
        <table>
          <caption>Leaderboard</caption>
          <tr>
            <th>#</th>
            <th>Camper Name</th>
            <th onClick={(e) => this.handleSort(e, 'recent')}><a href='javascript:void(0)'>Points in the past 30 days</a></th>
            <th onClick={(e) => this.handleSort(e, 'alltime')}><a href='javascript:void(0)'>All time points</a></th>
          </tr>
          {Object.keys(this.props.campers).map(key => {
            count++;
            return this.renderCampers(key, count);
          })}
        </table>
      </div>
    );
  }
}

/**
  Container
*/
class CamperLeaderboard extends React.Component {
  state = {
    campers: [],
    sort: 'recent'
  };

  getData() {
    let url = `https://fcctop100.herokuapp.com/api/fccusers/top/${this.state.sort}`
    const self = this;
    axios.get(url)
      .then(function (response) {
        self.setState({ campers: response.data });
        //console.log(self.state.campers);
      })
      .catch(function (error) {
        console.log(error);
      });
  }

  componentWillMount() {
    this.getData();
  }

  handleSort = (sort) => {
    this.setState({ sort: sort });
    this.getData();
  };

  render() {
    return (
      <div>
        <p>Click links in table header to sort</p>
        <Table campers={this.state.campers}
              handleSort={this.handleSort} />
      </div>
    );
  }
}

ReactDOM.render(<CamperLeaderboard />, document.getElementById('app'));

/*
To get the top 100 campers for the last 30 days: https://fcctop100.herokuapp.com/api/fccusers/top/recent.
To get the top 100 campers of all time: https://fcctop100.herokuapp.com/api/fccusers/top/alltime.
*/

最佳答案

我相信@finalfreq的解释是正确的,这就是解决方法。

像这样更新CamperLeaderboard类的handleSort方法:

handleSort = (sort) => {
  this.setState({ sort: sort });
  // You don't need to read sort from state. Just pass it :)
  this.getData(sort);
}

关于javascript - ReactJS状态没有改变,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41449739/

10-13 01:10