Redux 应用程序中每个减速器调用上深度复制状态有哪些缺点?

2024-04-14

进行深度复制是否有任何副作用state每次调用reducer函数时,在Redux应用程序中的appReducer上?

我这么问是因为不可变的更新模式 https://redux.js.org/recipes/structuring-reducers/immutable-update-patterns/Redux 的文档指出,要更新状态上的嵌套对象,您应该浅复制嵌套属性并更新它。

我很好奇在每个操作调用上对状态进行深度复制会产生什么副作用。

例如,这是一些伪代码

export default function appReducer(state = initialState, action){
let copiedState = JSON.parse(JSON.stringify(state))
switch(action){
  case action.UPDATE_NESTED_PROPERTY:
     copiedState.thing.anotherThing = somethingNew;
     return copiedState;
  case action.UPDATE_SOME_OTHER_NESTED_PROPERTY:
     copiedState.differentThing.nestedProperty = "updated";
     return copiedState;
  default:
     return state;
  }
}

始终深复制状态然后返回它的方法有什么不好?我还没有看到这样做,所以我假设它有问题。如果状态是一个巨大的对象,那么我确信每次进行深度复制可能会出现性能问题。但这会导致其他问题吗?


深度复制状态将导致所有 jsx 被重新创建,React 必须比较整个虚拟 dom,并可能重新渲染 DOM。重新渲染 DOM 是 Web 应用程序中最昂贵的操作之一,当您可以防止这种情况发生时,您应该这样做。

当调度一个动作并且reducer返回一个新状态时,所有回调都会传递给useState被调用,当它们返回与上次不同的值时,组件将重新创建 jsx.然后 React 会将 jsx 与上次进行比较,并可能重新绘制 DOM。

假设我有一个这样的容器:

const Container = React.memo(function Container({ id }) {
  const dispatch = useDispatch();
  //only if id changes will it re create the selector
  const selectItem = React.useMemo(
    () => createSelectItem(id),
    [id]
  );
  const item = useSelector(selectItem);
  //create remove function only when item has changed
  const remove = React.useCallback(
    //removeItem is an action creator
    () => dispatch(removeItem(item)),
    [item, dispatch]
  );
  //render component only when item changes
  return <Component item={item} remove={remove} />;
});

如果您在每个分派操作上重新创建整个状态(深层复制),那么该代码中的任何优化都不会执行任何操作。更糟糕的是item就这样改变了remove被重新创建,这意味着Component将会在 DOM 中重新渲染,因为处理函数发生了变化,即使item实际上可能没有改变它只是因为你深度复制了状态而改变了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Redux 应用程序中每个减速器调用上深度复制状态有哪些缺点? 的相关文章

随机推荐

  • 阅读 Whatsapp 消息

    我想创建一个 Android 应用程序来读取收件箱以及 Whatsapp 消息 我想做一个备份之类的东西 尽管可以在 Whatsapp 中选择这样做 但我想阅读这些消息 然后从我的应用程序中备份它们 我了解到 Whatsapp 在文件系统中
  • Symfony2表单类型实体添加额外选项

    我有以下 Symfony 表单字段 它是从实体加载的下拉列表 gt add measureunit entity array label gt Measure Unit class gt TeamERPBaseBundle MeasureU
  • Python正则表达式替换

    嘿 我正在尝试找出一个正则表达式来执行以下操作 这是我的字符串 Place 08 09 2010 15 531 2 909 650 我需要用逗号分隔该字符串 尽管由于数字数据字段中使用了逗号 但分割无法正常工作 所以我想在运行分割字符串之前
  • 处理和解决“网络使用过多(后台)”的正确方法

    问题背景 当前 我们面临 网络使用过多 背景 来自 Android Vital 报告 最后30天是0 04 但我们只是好于 9 过去 30 天 0 04 基准 优于 9 由于仅好于9 看起来像是一件可怕的事情 我们决定认真研究这个问题 该应
  • 如何在 x86_64 上准确地衡量未对齐访问速度?

    In 一个答案 https stackoverflow com questions 45116212 are packed structs portable 45116730 45116730 我已经说过 在很长一段时间内 未对齐访问的速度
  • 如何始终返回index.html Tomcat

    我有一个在 Tomcat 上运行的 Angular 应用程序 但由于我已经实现了路由 如果我手动访问一个 url 我会得到一个404未找到 另外 当发生错误时 它是一个基本的服务器页面 而不是我的错误 url 页面 如何配置 Tomcat
  • 引用表达式早期部分的匹配项的正则表达式

    我正在寻找一个正则表达式 它将标识一个序列 其中文本中的整数指定表达式末尾的尾随字母数 该具体示例适用于识别堆积格式的遗传数据中的插入和删除 例如 如果我正在搜索的文本是 AtT 3ACGTTT 1AaTTa 我需要匹配插入和删除 在本例中
  • 如何在客户端启动桌面应用程序

    在我的网页中 我必须在客户端计算机上启动桌面应用程序 如果已安装 知道我该怎么做吗 如果应用程序是 MS Office 或 Adob e Reader 我知道如何启动它们 但我要启动的应用程序是自定义应用程序 您无法在互联网上找到它 我如何
  • 如何使注册的符号不显示下划线?

    我遇到了问题 无法显示带有下划线的单词的一部分和没有下划线的单词的一部分 我希望 已注册 符号没有下划线 HTML h3 Basecamp span class sup reg span h3 CSS h3 font size 21px c
  • Rails:如果变量存在,则为输入字段设置一个值

    当 id 传递到控制器中的新操作时 我尝试为两个文本字段输入设置一个值 当前的代码可以工作 但我想知道是否可以缩短代码 当前代码 View div class custom input div
  • GStreamer 上的“列入黑名单”是什么意思?

    我正在尝试交叉编译 GStreamer 版本是1 2 3 主机PC的操作系统是x86 linux 目标系统的操作系统是MIPSEL linux操作系统 我成功为目标设备编译了 gstreamer 和插件 和gst launch 1 0可以被
  • 如何在 OnResponse 函数之外使用 Retrofit 响应?

    我想获取改造响应列表并在 OnResponse 函数之外使用它 但是当我尝试这样做时 我总是得到一个空对象 这是我的源代码 ApiInterface apiService ApiClient getClient create ApiInte
  • 为什么 Visual Studio Code 不断更改工作目录?

    我正在尝试使用 VS Code 来完成 Flask Web 开发 一书 我可以从命令行运行简单的 hello world 示例 但我想使用 VS 代码进行调试等 我修改 launch json 文件来构建 Flask 配置 name Fla
  • 企业库4数据配置标签

    我正在使用企业库来访问数据 当我运行应用程序时 在 CreateDatabase 语句中我收到此异常 Microsoft Practices ObjectBuilder2 BuildFailedException 未被用户代码处理 Mess
  • 在 Android 中从一个 Activity 移动到另一个 Activity

    我想从一项活动转移到另一项活动 使用虚拟设备 当我单击按钮移动时 我的模拟器会显示一个对话框unfortunately SMS1 has stopped working SMS1 是我的应用程序名称 有人可以帮助我纠正我的代码吗 MainA
  • & 符号使我无法使用 jQuery 加载 XML

    我在 XML 文档中显示描述 然后使用 jQuery 将其加载到应用程序中 当我尝试使用 时 它会破坏代码的加载 我也尝试过 38 它也不起作用 是否有解决方法可以让我在 XML 中包含 符号 编辑 结构是
  • ResultSet.getTimestamp("日期") 与 ResultSet.getTimestamp("日期", Calendar.getInstance(tz))

    java util Date java util Timetamp似乎给许多人带来了极大的困惑 StackOverflow 中有很多问题 不幸的是我的问题有点扭曲 有 2 个 JDBC api 他们应该如何表现 RDBMS 之间是否存在一致
  • 如何保存单选按钮状态

    我正在开发Android应用程序 其中我打开自己的自定义对话框 当我选择单选按钮时 我使用单选按钮 毫无疑问它被选中并工作 但是当我再次打开对话框时 所有单选按钮都被取消选择 我想保存上一个按钮的状态 enter code here pri
  • Android AlertDialog 标题字体

    我正在尝试更改字体android support v7 app AlertDialog标题文本 方法一 TextView title TextView dialog findViewById android R id title retur
  • Redux 应用程序中每个减速器调用上深度复制状态有哪些缺点?

    进行深度复制是否有任何副作用state每次调用reducer函数时 在Redux应用程序中的appReducer上 我这么问是因为不可变的更新模式 https redux js org recipes structuring reducer