【问题标题】:React: Given an array, render the elements in reverse order efficientlyReact:给定一个数组,以相反的顺序有效地渲染元素
【发布时间】:2016-06-06 18:04:20
【问题描述】:

我目前以典型的 React 风格呈现一个列表。该列表作为数组道具传递,我像这样映射它:

{this.props.myList.map(createListItem, this)}

所以当一个新元素被添加时,它看起来就像最新的项目被添加到了列表的末尾。

我想要它,所以最新的项目出现在顶部。即一切都按时间倒序出现。

到目前为止,我提出的两个选项是: 1)反转列表,每次添加东西时创建一个新数组,并将这个反转的列表作为道具传递。 2) 使用移位。

但由于性能,它们都没有吸引力。

我不知道 Javascript 支持反向映射。我一直在尝试一个 for 循环,但我无法让它工作。

在 React 中以相反顺序呈现数组的惯用方式是什么?

【问题讨论】:

  • this.props.myList.reverse().map 是一个选项吗?
  • 我认为使用本机 reverse() 方法不是一个坏主意。在谷歌浏览器中 array.reverse 比其他方法更快但是,如果性能真的是一场音乐会,你可以使用答案中描述的方法stackoverflow.com/questions/5276953/…
  • 我想你可能想多了。您建议的两种方法都可以在 map 性能要好得多。

标签: javascript reactjs


【解决方案1】:

如果您选择使用reverse()、shift() 或splice() 反转列表,则应先制作数组的浅表副本,然后在副本上使用该函数。 React 中的 props 不应该被改变。

例如:

[...this.props.myList].reverse().map(createListItem, this)

或

this.props.myList.slice(0).map(createListItem, this)

(这确实应该是一个评论,但我还没有这样做的重点:))

【讨论】:

  • 在 4 秒内工作。我需要更多时间来写这篇评论!谢谢!
  • 是的,非常感谢!我的一系列图片出现了眨眼问题,您保存了我的设计!
  • 你帮我写了这段代码。谢谢你。 this.state.ALLProducts.reverse().map((ALLProducts) =>
  • 此方法也适用于状态React.useState((current)=>[...current].reverse()) 如果您不使用扩展运算符,则它不起作用。 (用一组对象“测试”)
【解决方案2】:

如果您需要在 UI 中以相反的顺序显示列表,您也可以使用

flex-direction: row-reverse;

或

flex-direction: column-reverse;

【讨论】:

  • 没想到这个,而不是 reverse() , flex-direction 效果很好。感谢您提供这个独特的解决方案。
  • 非常感谢这种无需额外使用 CPU 来反转记录的方法
【解决方案3】:

正如其他人指出的那样,谦虚的反向方法在大多数情况下都可以完成这项工作。我目前遇到了同样的问题,我必须说至少在 Chrome 中使用 array.reverse() ,性能损失并没有被视为这样。在我看来,它比使用循环以相反的顺序对列表进行排序要好。

 array.reverse()

【讨论】:

    【解决方案4】:

    在使用array.reverse() 时,只要状态发生变化,顺序就会发生变化。我选择了flexDirection:'column-reverse',它工作得很好,你也不需要弄乱数组数据。

    【讨论】:

    • 反向修改数组,你可以做 array.slice().reverse() 来反转数组的副本
    【解决方案5】:

    在数组的开头添加新元素:

    array.splice(0,0,'value to add at beginning');
    

    或者使用立即调用的函数调用 for 循环:

    {(() => {
         for(...) {
             return (<i>{whatever}</i>)
         }
    })()}
    

    【讨论】:

    • 我更喜欢 array.unshift(val)
    • 没错,我不知道我为什么跳到splice :)
    【解决方案6】:

    不断推入数组,渲染的时候可以简单的使用

    Array.reverse()
    

    这里是documentation

    提醒它会变异原来的那个

    【讨论】:

      【解决方案7】:

      当使用mobx 作为存储时,可以为反转数组创建一个computed 属性,每次原始observable array 更改时都会重新评估和记忆该属性。

      商店

      import { observable, computed } from 'mobx';
      
      class MyStore {
        @observable items = [1, 2, 3];
      
        @computed get itemsReversed() {
          return this.items.slice().reverse();
        }
      }
      
      export default MyStore;
      

      渲染

      import React, { Component } from 'react';
      import { inject, observer } from 'mobx-react';
      
      @inject('myStore') @observer
      class List extends Component {
        render() {
          const { myStore } = this.props;
          const { itemsReversed } = myStore;
          return (
            <div className="list">
              {itemsReversed.map(item => (
                <div className="list-item">{item}</div>
              ))}
            </div>
          );
        }
      }
      
      export default List;
      

      根据官方文档,这是反转数组的首选方法:

      与函数sort 和reverse 的内置实现不同,observableArray.sort 和reverse 不会就地更改数组,而只会返回排序/反转的副本。从 MobX 5 及更高版本开始,这将显示警告。建议改用array.slice().sort()。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-06-25
        • 2020-12-02
        • 1970-01-01
        • 1970-01-01
        • 2020-03-01
        • 2016-02-18
        • 1970-01-01
        相关资源
        最近更新 更多