【问题标题】:React State Change Not Causing component to Re-Render反应状态更改不会导致组件重新渲染
【发布时间】:2015-11-03 03:36:30
【问题描述】:

我还是 ReactJS 的新手,我遇到了一些障碍。我正在尝试在 React 组件中实现分页;但是,即使我的分页函数被成功调用,状态更改也不会导致组件再次渲染。

我使用一个函数获取初始数据 (getMainFeed),然后使用第二个函数 (getMoreItems) 进行分页。第二个函数由我的“handleScroll”函数调用。有趣的是,当我用“getMainFeed”函数替换“getMoreItems”函数时,状态变化会导致组件完美地呈现附加数据。不幸的是,我需要使用这两个单独的 API,而且我认为将这两个调用组合到一个函数中并不合适。那么有没有办法让我获得“getMoreItems”来将新项目呈现到屏幕上?

var data = [];


var GridView = React.createClass({
  getInitialState: function() {
    window.addEventListener("scroll", this.handleScroll);
    return {
      data: [],
      page: 0,      //for pagination
      loadingFlag: false,
    };
    },

  getMainFeed: function() {

    var nextPage = 1; //increase the page count
    ajax_url = "http://127.0.0.1:8200/api/content/main/";
    ajax_type = "GET";
    ajax_data = {
       'BatchCount': "20"
    };

    $.ajax({
       url: ajax_url,
       type: ajax_type,
       contentType: 'application/x-www-form-urlencoded',
       data: ajax_data,

       dataType: 'json',

    success: function(data) {
      this.setState({
        data: data,
        loadingFlag:false,
        page: 2

      });
      //loading("off");
    }.bind(this),
    error: function(xhr, status, err) {
      console.error(this.props.url, status, err.toString());
    }.bind(this)

    });

   }, //end function
   getMoreItems: function() {
    var nextPage = this.state.page+1; //increase the page count
    ajax_url = "http://127.0.0.1:8200/api/content/page/1/";
    ajax_type = "GET";
    ajax_data = {
       'BatchCount': "20"
    };

    $.ajax({
       url: ajax_url,
       type: ajax_type,
       contentType: 'application/x-www-form-urlencoded',
       data: ajax_data,

       dataType: 'json',

    success: function(data) {
      this.setState({
        data: data,
        loadingFlag:false,
          page: nextPage
      });

    }.bind(this),
    error: function(xhr, status, err) {
      console.error(this.props.url, status, err.toString());
    }.bind(this)
    });

 }, //end function
  componentDidMount: function() {
    //loading("on");
    this.getMainFeed();
  },
  handleScroll:function(e){
    //this function will be triggered if user scrolls
    var windowHeight = $(window).height();
    var inHeight = window.innerHeight;
    var scrollT = $(window).scrollTop();
    var totalScrolled = scrollT+inHeight;
    if(totalScrolled+1200>windowHeight){  //user reached at bottom
      if(!this.state.loadingFlag){  //to avoid multiple request 
          this.setState({
            loadingFlag:true,  
          });
          //loading("on");
          this.getMoreItems();
      }
    }
  },
  componentDidUpdate: function() {

    $('#grid-container').imagesLoaded( function() {
      MasonryInit();
    }); 
  },
  render: function() {
      return (
        <div id="feed-container-inner">
          <GridMain data={this.state.data} />
        </div>

      );
    }
  });

【问题讨论】:

  • successgetMoreItems 中执行吗?
  • 是的,成功总是被称为。我没有正确设置数据。

标签: javascript pagination reactjs infinite-scroll


【解决方案1】:

问题是我没有像data: this.state.data.concat(data),那样将数据连接到现有数据的末尾。

这让我很吃惊,因为我原以为 getMoreItems 函数会简单地替换现有数据。

【讨论】:

  • 这没有意义。我认为渲染功能被触发并且您的视图重新渲染,但是格式不好并且您的视图无法显示它。即使重新渲染。
  • 另外你不应该通过'this.state'改变状态。您应该始终通过 setState 进行更改。来自 setState 的 react.js 实现:设置状态的子集。始终使用它来改变状态。您应该将 this.state 视为不可变的。
  • JavaScripts Array.concat 返回一个新数组而不修改现有数组,所以像这样使用就可以了。见MDN docs
【解决方案2】:

当状态改变时,它会重新渲染。您还看到它正在与您的 getmainfeed 功能一起使用。

所以我认为你的 getmoreitems 函数只是不成功。你确认这个调用成功了吗?

【讨论】:

  • 不,函数总是成功的。原来我必须连接数据
猜你喜欢
  • 1970-01-01
  • 2019-03-07
  • 2020-10-19
  • 2017-03-24
  • 2019-04-03
  • 2021-11-07
  • 1970-01-01
  • 2022-07-08
  • 2016-02-23
相关资源
最近更新 更多