【问题标题】:Updating state in react-native taking foreverreact-native 中永久更新状态
【发布时间】:2016-03-03 08:16:22
【问题描述】:

我添加了“喜欢”帖子的功能。 突然间,react-native 正以蜗牛般的速度爬行。 我是新手,所以不确定何时何地正确设置状态。

我应该如何在 listView 表中正确附加喜欢一行的功能??

代码如下...

要点击的“喜欢”文本是这样的......

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

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

我更新状态是否错误? setState 的成本是多少?我认为 react 应该只是重新渲染它在虚拟 DOM 中看到的更改。为什么它看起来像是重新渲染我的整个 listView。为什么加载时间超过 1 分钟? (某处明显内存泄漏)??

另外,是否可以只增加“DOM”上的整数而不触发重新渲染?

【问题讨论】:

    标签: javascript react-native


    【解决方案1】:

    渲染你的 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 或其他选项。

    【讨论】:

    • 欣赏答案,但这不是我的问题。这是我的错,因为重新阅读我的问题,我可以看到你是如何采取这种方式的......但我已经知道如何传递行 ID,在这种情况下我什至没有这样做。我在一行中单击一个文本项。无论如何....我的问题不是怎么做,而是怎么做,所以渲染时间不会太长。您的答案更新状态与我更新它的位置相同。 (在 onPress 功能中)。问题是为什么重新渲染会丢失超过 100 帧。另外,在我的示例中,我没有复制 state 吗?
    【解决方案2】:

    由于 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 monitor查看调试信息。

    【讨论】:

    • 嗯.... 现在它甚至在把它放在那里之后根本没有更新。另外,我是否正确更新状态?就像我做对了吗?通过复制之前的状态,然后将新变量 d 放在旧状态的位置?
    • 哦,是的,尝试将您的 Text 标签包装在 TouchableHighlight 中并将 onPress 移动到 TouchableHighlight
    • 不是触摸事件不起作用。该功能触发良好。数据在我的数组中更新。它是状态的实际设置,所以我可以直观地看到要么现在不起作用,要么永远持续下去的变化。所以这是我真正的问题。如何正确设置状态以使一切正常。
    猜你喜欢
    • 2021-10-23
    • 1970-01-01
    • 1970-01-01
    • 2020-09-06
    • 2020-04-24
    • 2022-01-22
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    相关资源
    最近更新 更多