如何添加新元素而不用React重新渲染整个列表

尼古拉·阿列什科夫斯基(Nikolay Aleshkovskiy)

我正在开发简单的流应用程序。我有帖子列表,此列表可以接收更新,更新将显示在其顶部。

问题是,在每个新帖子上,React都会重新渲染整个元素列表。我为此做了一个简单的例子。

有什么办法可以避免这种行为?我已经在React docs上看到了dynamic-children主题,但是在示例中(如您所见),无论如何我都更新了所有子项。

class Post extends React.Component {
  render() {
    console.log('rerendered post', this.props.reactKey);
    return (
      <li>{this.props.post.text}</li>
    );
  }
}

class App extends React.Component {

  constructor(props) {
    super(props);
    this.state = {posts: [
      {id: '00001', text: 'First one'},
      {id: '00002',text: 'Second one'},
      {id: '00003',text: 'Third one'}
    ]};
  }

  addPost() {
    const posts = this.state.posts;
    posts.unshift({id: '00004', text: 'New post'});
    this.setState({posts: posts});
  }

  render() {
    return (
      <div>
        <button onClick={this.addPost.bind(this)}>Add Post</button>
        <ul>
          {this.state.posts.map((post, index) => {
            return (<Post post={post} key={post.id} reactKey={index} />);
          })}
        </ul>
      </div>
    );
  }
}


ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<body>
  <div id="root"></div>
</body>

解决方案

问题是我使用.map函数的索引是每个列表组件的键,而不是唯一键。并且由于在添加新元素以列出所有索引之后将其更改为+1,因此第一条帖子成为第二条帖子,因此我的所有帖子都已重新呈现。因此,首先,请检查您是否在所有列表元素中使用唯一键:-)

罗斯·艾伦

只需要执行一次的工作应该在保证只能运行一次的生命周期方法中完成,例如componentDidMount正如文档所建议的:

如果要与其他JavaScript框架集成,请使用setTimeout或setInterval设置计时器,或发送AJAX请求,请使用此方法执行这些操作。

componentDidMount在您的代码段中添加了日志记录,以显示渲染发生了很多次,但是componentDidMount每个实例仅被调用一次。

class Post extends React.Component {
  componentDidMount() {
    console.log('mounted post', this.props.id);
  }

  render() {
    console.log('rerendered post', this.props.id);
    return (
      <li>{this.props.post.text}</li>
    );
  }
}

class App extends React.Component {

  constructor(props) {
    super(props);
    this.nextId = 4;
    this.state = {
      posts: [
        {id: 1, text: 'First one'},
        {id: 2,text: 'Second one'},
        {id: 3,text: 'Third one'},
      ],
    };
  }

  addPost() {
    const posts = this.state.posts;
    posts.unshift({id: this.nextId, text: 'Post ' + this.nextId});
    this.nextId++;
    this.setState({posts: posts});
  }

  render() {
    return (
      <div>
        <button onClick={this.addPost.bind(this)}>Add Post</button>
        <ul>
          {this.state.posts.map((post, index) => {
            return (<Post post={post} key={post.id} id={post.id} />);
          })}
        </ul>
      </div>
    );
  }
}


ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<body>
  <div id="root"></div>
</body>

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何避免重新渲染整个列表,而不是将新项目添加到react JS中的DOM列表中?

来自分类Dev

React Redux + Infinite Scroll =重新渲染整个列表?

来自分类Dev

React - InfiniteScroll(react-infinite-scroller), loadMore 函数重新渲染整个列表

来自分类Dev

更改单个项目时重新渲染整个列表

来自分类Dev

在ReactJs React-Redux中仅创建或更新列表中的一个项目时,如何停止重新渲染整个项目列表?

来自分类Dev

Angularjs重新渲染整个页面[ionic]

来自分类Dev

重新渲染整个ng-repeat

来自分类Dev

渲染组件后,React重新渲染整个应用程序

来自分类Dev

在具有Redux状态的React中重新渲染整个表单

来自分类Dev

React Router重新渲染整个应用并重置Redux状态树?

来自分类Dev

React Native:通过setState更新ListView数据源是否会重新渲染整个组件?

来自分类Dev

如何在不重新渲染整个屏幕的情况下放大/缩小OpenGL屏幕

来自分类Dev

添加新元素后如何更新列表

来自分类Dev

Angular会重新渲染整个对象吗?

来自分类Dev

如何在 ReactJS 中不重新渲染整个树的情况下渲染树组件的叶子组件

来自分类Dev

如何防止map()在react-native中一次渲染整个数组

来自分类Dev

如何在背景上渲染整个图像?

来自分类Dev

为什么画布重新渲染整个画布而不是仅渲染特定部分?

来自分类Dev

为什么画布重新渲染整个画布而不是仅渲染特定部分?

来自分类Dev

如何将新元素添加到列表?

来自分类Dev

添加新元素时如何刷新列表视图

来自分类Dev

LibGDX:渲染TextureRegion渲染整个纹理

来自分类Dev

如何在React中更新元素列表

来自分类Dev

用于倒数计时器的useEffect,每秒重新渲染整个页面

来自分类Dev

更改特定索引而无需在Vuejs中重新渲染整个数组

来自分类Dev

输出组件循环并避免仅更新一个组件时重新渲染整个循环

来自分类Dev

如果特定道具发生变化,则重新渲染整个组件

来自分类Dev

Ember 每个循环在更新数组时重新渲染整个对象数组

来自分类Dev

将新元素添加到列表

Related 相关文章

  1. 1

    如何避免重新渲染整个列表,而不是将新项目添加到react JS中的DOM列表中?

  2. 2

    React Redux + Infinite Scroll =重新渲染整个列表?

  3. 3

    React - InfiniteScroll(react-infinite-scroller), loadMore 函数重新渲染整个列表

  4. 4

    更改单个项目时重新渲染整个列表

  5. 5

    在ReactJs React-Redux中仅创建或更新列表中的一个项目时,如何停止重新渲染整个项目列表?

  6. 6

    Angularjs重新渲染整个页面[ionic]

  7. 7

    重新渲染整个ng-repeat

  8. 8

    渲染组件后,React重新渲染整个应用程序

  9. 9

    在具有Redux状态的React中重新渲染整个表单

  10. 10

    React Router重新渲染整个应用并重置Redux状态树?

  11. 11

    React Native:通过setState更新ListView数据源是否会重新渲染整个组件?

  12. 12

    如何在不重新渲染整个屏幕的情况下放大/缩小OpenGL屏幕

  13. 13

    添加新元素后如何更新列表

  14. 14

    Angular会重新渲染整个对象吗?

  15. 15

    如何在 ReactJS 中不重新渲染整个树的情况下渲染树组件的叶子组件

  16. 16

    如何防止map()在react-native中一次渲染整个数组

  17. 17

    如何在背景上渲染整个图像?

  18. 18

    为什么画布重新渲染整个画布而不是仅渲染特定部分?

  19. 19

    为什么画布重新渲染整个画布而不是仅渲染特定部分?

  20. 20

    如何将新元素添加到列表?

  21. 21

    添加新元素时如何刷新列表视图

  22. 22

    LibGDX:渲染TextureRegion渲染整个纹理

  23. 23

    如何在React中更新元素列表

  24. 24

    用于倒数计时器的useEffect,每秒重新渲染整个页面

  25. 25

    更改特定索引而无需在Vuejs中重新渲染整个数组

  26. 26

    输出组件循环并避免仅更新一个组件时重新渲染整个循环

  27. 27

    如果特定道具发生变化,则重新渲染整个组件

  28. 28

    Ember 每个循环在更新数组时重新渲染整个对象数组

  29. 29

    将新元素添加到列表

热门标签

归档