【问题标题】:"Reselect" VS "Memoize-One" with "React and Redux"“Reselect” VS “Memoize-One” 与 “React and Redux”
【发布时间】:2019-03-19 12:42:20
【问题描述】:

我正在尝试在我的 React 工作流程中使用某种记忆,我正在寻找最好且最重要的 “最简单” 解决方案来与我的工作流程集成,其中包括 @ 987654321@.

我看到了很多关于 memoization 的文章,有些文章展示了“memoize-one”的使用,并将其作为最快和最容易启动和运行的工具,而其他人甚至没有提及它并谈论“重新选择”。

我只想知道哪个更好、最简单,我应该投资哪个。

【问题讨论】:

  • reselect 是专门为 redux 设计的。可能很适合你

标签: reactjs redux react-redux memoization reselect


【解决方案1】:

两个返回一个函数,该函数接受给定数量的参数返回一个值

getA(arg1, arg2, arg3) // Returns a value

不同之处在于调用函数时在底层会发生什么。

memoize-one

  • 收集提供的参数
  • 将参数与之前调用中提供的参数进行比较 (===)
  • 参数相同:返回缓存结果
  • 参数 不一样:重新评估结果函数并返回

重新选择

  • 收集提供的参数
  • 运行一组inputSelectors 函数,为它们提供收集到的参数
  • 收集inputSelectors返回值
  • inputSelectors返回值与之前调用(===)中获得的值进行比较
  • 相同:返回缓存结果
  • 不一样:重新评估结果函数并返回

结论

memoize-one 是一个基于值的记忆实用程序:记忆提供的参数的值执行。

reselect 在其之上添加了一个进一步的评估层:memoization 不是在参数值上执行,而是在 inputSelectors 函数集的结果 上执行那些最初的论点。

这意味着reselect 选择器很容易组合,因为每个inputSelectors 可以是另一个reselect 选择器。

【讨论】:

    【解决方案2】:

    我没有使用重新选择,但是当我想从渲染中的道具计算某些东西时,memoize-one 对我来说非常有用。这是一个很好的模式,用于执行昂贵的操作,比如映射一个大数组,道具可能会随着时间的推移而变化,但在某些重新渲染时也可能不会改变。它确保仅在输入更改时才重新计算渲染中使用的昂贵操作。它还避免了必须使用诸如 getDerivedStateFromProps 之类的生命周期方法(如果它可以从 props 计算,它可能不应该处于状态)。

    import memoize from 'memoize-one'
    
    class Example extends Component {
    
      mapList = memoize(
        (list) => list.map(item => ({text: item.text}))
      )
    
      render() {
        // if this.props.list hasn't changed since the last render
        // memoize-one will re-use the last return value from cache
        const mappedList = this.mapList(this.props.list)
    
        return (
          ...
        )
      }
    }
    

    请记住,在大多数情况下,您需要将记忆函数附加到组件实例而不是使用静态类变量。这可以防止一个组件的多个实例重置彼此的记忆键。

    【讨论】:

      【解决方案3】:

      我建议使用reselect,因为它是专门为与 React/Redux 一起使用而设计的。 memoize-one 更像是一个通用的记忆库。

      reselect 真的很容易使用,它只是包装了你的选择器:

      import { createSelector } from 'reselect';
      
      const shopItemsSelector = state => state.shop.items;
      
      // without reselect
      const subtotalSelector = state => {
        const items = shopItemsSelector(state);
        return items.reduce((acc, item) => acc + item.value, 0);
      }
      
      // with reselect
      const subtotalSelector = createSelector(
        shopItemsSelector, // list the selectors you need
        items => items.reduce((acc, item) => acc + item.value, 0) // the last argument is actual selector
      )
      

      【讨论】:

      • 很好的解释。我认为当我们将状态传递给函数并且我们需要运行一组输入选择器时,重新选择主要是有用的。当函数只接受几个变量参数时,单一记忆会很有用。
      猜你喜欢
      • 2017-06-06
      • 2019-09-27
      • 1970-01-01
      • 2018-07-03
      • 1970-01-01
      • 2020-08-07
      • 1970-01-01
      • 2018-05-16
      • 2019-01-20
      相关资源
      最近更新 更多