【问题标题】:Is it important to `memoize` with Redux?使用 Redux 进行“记忆”重要吗?
【发布时间】:2018-12-19 17:40:15
【问题描述】:

在阅读了大量关于 React、Redux 和 memoization 的文章后,我想问一个问题……我可以摆脱这个用例吗:

假设我有一个包含以下数据的 redux 存储

// reduxStore
module.exports = {
    randomData: [
        { name: 'John', age: 30 },
        { name: 'Peter', age: 25 },
        { name: 'Brenda', age: 15 }
    ];
};

现在,在我的组件中,我想检索平均年龄。我是这样处理的:

import React from 'react';
import { connect } from 'react-redux';

export function TestComponent(props) {
    return <p>The sum of ages is: {props.ageSum}</p>;
}

const mapStateToProps = state => ({
    ageSum: state.randomData.map(datum => datum.age).reduce((acc, curr) => acc + curr)
});

const mapDispatchToProps = {};

export default connect(mapStateToProps, mapDispatchToProps)(TestComponent);

我的印象是,这与 reselect 给出的示例以及 React 推荐的其他库相同。

有人可以解释一下,这个例子在优化方面是否以及为什么不明智...

【问题讨论】:

  • 除非state.randomData发生变化,否则组件不会被重新渲染,如果确实发生变化,则必须重做计算,所以无论如何使用记忆化没有意义

标签: javascript reactjs redux react-redux


【解决方案1】:

该示例可以工作,但对于性能来说并不是最好的。

在大多数情况下,在您的mapStateToProps 函数中调用map() 将导致返回一个新的数组引用。不同的引用意味着结果不等于上次的浅,因此您的组件将重新渲染。记忆化有助于确保您仅在输入值实际发生变化时才生成新的引用(如 someArray.map())。

在您的情况下,map 结果会立即输入reduce(),并用于计算总和。假设每次计算的总和都相同,您的组件将不会重新渲染,因此不必担心。

但是,state.randomData 很可能大部分时间都没有改变,在这种情况下,map().reduce() 正在做不必要的工作。记忆化也有助于避免这种情况。

请参阅React-Redux docs on writing mapState functions 和我的帖子Idiomatic Redux: Using Reselect Selectors for Encapsulation and Performance 了解更多详情。

【讨论】:

  • 那么,你能用一个额外的例子来澄清每个name 值在每个randomData 元素中的情况吗?如果我理解清楚,这意味着当name 值更改时,memoization 不会重新渲染,但会在age 更改时重新渲染
  • 不可变地更新数据意味着复制所有受影响的值并修改它们。如果我想将“Peter”更改为“Fred”,我需要复制和修改state.randomData[1] 的对象、state.randomData 的数组和state 的对象。这些都会产生新的对象/数组引用。理想情况下,您的 mapState 函数只会在 state.randomData 是一个新的数组引用时重新计算总和(这表明它的某些内容已更改)。
  • 我感觉这个例子并没有真正在我的方法和记忆之间发挥出最好的效果。您能否提供一个更好地澄清它的@markerikson?谢谢
  • 翻转请求:你能澄清一下实际问题是什么吗? :)
猜你喜欢
  • 2016-02-11
  • 2022-11-03
  • 1970-01-01
  • 1970-01-01
  • 2015-06-24
  • 2018-01-05
  • 2012-09-20
  • 1970-01-01
  • 2014-03-23
相关资源
最近更新 更多