在反应本机中更新状态需要很长时间

Updating state in react-native taking forever

本文关键字:长时间 状态 更新 本机      更新时间:2023-09-26

我添加了"喜欢"帖子的功能。突然间,反应原生正在以蜗牛的速度爬行。我是新手,所以不确定何时何地正确设置状态。

我应该如何在列表视图表中正确附加喜欢行的功能?

这是代码...

要点击的"喜欢"文本是这样的。

 <Text onPress={this.likePost.bind(this, feeditem.post_id)}>{feeditem.likes} likes</Text>

那么"喜欢"功能就是这个...

likePost(id){
  if(this.state.feedData!=null){
    var d = this.state.feedData;
    // Find row by post_id
    var ix = d.findIndex(x => x.post_id===id);
    // Only set state if user hasn't already liked
    if(d[ix].you_liked==0){
      // Mark as liked, and increment
      d[ix].you_liked=true;
      d[ix].likes = parseInt(d[ix].likes)++;
      // Set the state after liking
      this.setState({
        feedData: d,
        feedList: this.state.feedList.cloneWithRows(d)
      });
    }
  }
}

它可以工作,并且可以正确更新数据,并且可以很好地显示在开发工具中。 但是,新状态的视觉渲染需要一分钟多的时间。

我更新的状态有误吗?设置状态的成本是多少?我认为 react 应该只是重新渲染它在虚拟 DOM 中看到的变化。 那么为什么它看起来像是重新渲染我的整个列表视图。 为什么加载时间超过 1 分钟?(某处明显的内存泄漏)??

另外,是否可以在不触发重新渲染的情况下仅增加"DOM"上的整数?

渲染你的ListView传递dataSourcerenderRow道具

render() {
  return (
    <ListView
    dataSource={this.state.dataSource}
    renderRow={this._renderRow}/>
  );
}

创建renderRow函数,您可以在其中访问点击行的数据和索引

_renderRow = (rowData, sectionIndex, rowIndex, highlightRow) => {
  return (
    <TouchableOpacity onPress={() => {
        //Here you shoud update state
    }}/>
  );
};

此外,在操作状态之前,您始终需要复制状态,因为它是不可变的对象。尝试使用状态变异库,使用 https://facebook.github.io/react/docs/update.html 或其他选项。

由于 chrome 调试器,动画可能需要很长时间。缓解此问题的一个小方法是使用InteractionManager

likePost(id){
  InteractionManager.runAfterInteractions(() => {
    if(this.state.feedData!=null){
      var d = this.state.feedData;
      // Find row by post_id
      var ix = d.findIndex(x => x.post_id===id);
      // Only set state if user hasn't already liked
      if(d[ix].you_liked==0){
        // Mark as liked, and increment
        d[ix].you_liked=true;
        d[ix].likes = parseInt(d[ix].likes)++;
        // Set the state after liking
        this.setState({
          feedData: d,
          feedList: this.state.feedList.cloneWithRows(d)
        });
      }
    }
  });
}

或者禁用 chrome 调试并使用 android 监视器查看调试消息。