React 是否保证“props”对象引用保持稳定?

2023-12-25

最近我看到类似于以下人为示例的代码:

const MyComp = props => {
  const [prevProps, setPrevProps] = useState(props)

  if (props !== prevProps) {
    setPrevProps(props);
    // do something else...
  }
}

该组件使用某种派生状态来记住之前的 props。如果内存位置为props已经改变 (props !== prevProps),它将把新的 props 同步到useState.

是的,这没有多大意义,但我的观点是:React 是否做出任何保证,props保持不变,假设没有包含属性props已经改变?

至少,我所做的测试似乎是这样。如果父组件更改任何 props,将会有一个新的props对象已创建。

我将不胜感激任何证明这一点的官方文档链接。


如果 props 包含的属性没有改变,React 是否保证 props 的对象引用保持不变?

不,事实并非如此。

如果父组件更改任何 props,将会创建一个新的 props 对象。

如果父级重新渲染,孩子将始终在新对象中接收其道具,即使其中没​​有任何改变。

如果你想阻止这种情况,你将不得不使用PureComponent or React.memo https://reactjs.org/docs/react-api.html#reactmemo这将对所有属性进行浅层相等比较props对象并防止重新渲染(如果它们都没有改变)。

const { memo, useState, useEffect } = React;

const Child = props => {
  // only gets called when `props` changes
  useEffect(() => console.log(props.name, ": props changed"), [props]); 

  return <p>{props.name}: {props.text}</p>;
};

const MemoChild = memo(Child);

const Parent = () => {
  const [count, setCount] = useState(0);
  const [text, setText] = useState("foo");
  const handleTextChange = event => setText(event.target.value);

  return (
    <div>
      <button onClick={() => setCount(c => c + 1)}>
        Click to force Re-Render
      </button>
      <input id="text" value={text} onChange={handleTextChange} />
      <Child name="Child without memo()" text={text} />
      <MemoChild name="Child with memo()" text={text} />
    </div>
  );
};

ReactDOM.render(<Parent />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>

看看这个例子。你会看到当你按下按钮时,孩子没有使用memo会重新渲染,即使 propsname or text没有改变。仍然会收到新的props object.

但是当您在输入中输入某些内容时,两个组件都会重新渲染,因为text道具的属性发生了变化。

还应该注意的是,这只是性能优化。你不应该依赖memo始终防止重新渲染。

该方法仅作为性能优化 https://reactjs.org/docs/optimizing-performance.html。不要依赖 它是为了“阻止”渲染,因为这可能会导致错误。

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

React 是否保证“props”对象引用保持稳定? 的相关文章

  • Exceljs:迭代每行和每列的每个单元格

    我想在所有单元格中添加粗边框 这是一个有角度的项目 我正在使用打字稿 我可以为 1 个单元格做到这一点 worksheet getCell A1 border top style thick left style thick bottom
  • 如何在React-Native中选择ListView的一项?

    我是 React Native 的新手 我想使用 ListView 选择一项 当我第一次按下 item 时 ListView renderRow 被调用 但终究不起作用 我该如何修复这个错误 我的问题出在哪里 我写了一个演示here htt
  • Node.js Google-云存储上传目的地规范

    我有一个 Node js 服务器并且正在使用谷歌云上传一些图像文件的包Firebase 存储 上传本身工作正常 但 google cloud API 似乎只能将文件上传到 Firebase Storage 根文件夹 有没有办法指定远程位置来
  • 如何根据另一个动态下拉列表的值创建动态下拉列表?

    我有一个下拉菜单 当我选择一个选项时 它会创建一个动态下拉菜单 到目前为止 一切都很好 但我想创建另一个动态下拉列表 现在基于另一个动态下拉列表的值 我该怎么做 第一个动态下拉列表有效 我猜第二个无效 因为动态变量 div 没有静态 ID
  • 为什么我的箭头函数有原型属性?

    正如文档中提到的https developer mozilla org en docs Web JavaScript Reference Functions Arrow functions https developer mozilla o
  • 强制执行 show.bind

    我有一个包含数据的表 当从另一个视图触发事件时 我希望视图检查 show bind 语句 问题是该事件没有更改当前视图中的任何数据 foo html tr p canBeRemoved p tr 我正在使用 EventAggregator
  • 将 javascript 放在 header 之外有多糟糕?

    这个问题几乎已经说明了一切 我开始添加一些功能到我的周末项目 http www my clock net 对于我和几个朋友来说 这是一个小应用程序 因为我们是交换生 所以它对我们来说有点有用 但事情是这样的 我在 php 中执行此操作并使用
  • 按日期对 JSON 进行排序

    我知道这一定相对简单 但我有一个 JSON 数据集 我想按日期排序 到目前为止 我每次都会遇到问题 现在我将日期存储为this lastUpdated 如果有帮助的话 我可以访问 jquery 但我意识到 sort 是本机 JS 提前致谢
  • Javascript“命名空间”和 jQuery AJAX

    我正在使用此处列出的建议 http www odetocode com articles 473 aspx http www odetocode com articles 473 aspx 使用模拟的JavaScript AJAX网络聊天系
  • React JS“this”没有按预期工作

    我有下面的代码 save function var this this console log this refs itemText this setState isEditing false function console log In
  • 上传前如何检查图片的宽度和高度

    对于图片上传 我编写了以下 html 代码
  • 如何在 Next.js 中正确使用 Mongoose 模型?

    我正在使用 TypeScript 和 MongoDB Mongoose 构建 Next js 应用程序 我在使用 Mongoose 模型时开始遇到错误 这导致它们在每次使用模型时都尝试覆盖模型 导致模型覆盖错误的代码 import mong
  • 用于图形操作的 Javascript 库

    有没有建议的 javascript 替代 pythonpygraph http code google com p python graph or NetworkX http networkx lanl gov 应该注意的是 可视化不是必需
  • 加载 angularjs 路由后运行 javascript 代码

    我需要在 angularjs 加载路线后显示警报 显示警报的代码位于 angularjs 异步加载的视图中 视图加载后 我希望它能够运行 但它没有 我知道我可以广播并告诉它稍后运行等 但我需要一个更通用的解决方案 假设您正在谈论基于以下内容
  • 限制线的长度

    我正在尝试画一条代表 弹弓 的线 并且希望它具有最大拉伸长度 在 p5 中 我在位置和位置之间画了一条线 line posA x posA y posB x posB y posA 是鼠标 x 和 y posB 是画布上圆的位置 我想要做的
  • onClick 事件适用于触摸屏设备上的触摸吗?

    我用过onclick我的网站上的活动 但是 当我在谷歌浏览器的开发人员模式移动视图中打开它时 触摸使用鼠标单击的元素没有任何反应 所以我的问题是 我还必须添加吗ontouch事件连同onclick事件或 onClick 事件适用于所有触摸屏
  • Antd select 元素:如何禁用输入?

    我正在尝试使用模式 multiple 的选择元素 我希望禁用输入 这意味着用户只能在现有选项之间进行选择 而不能输入文本 我该怎么做呢 我的元素 import Select from antd import antd dist antd c
  • 自动更改 Twitter Bootstrap 选项卡

    我希望 Twitter Bootstrap 选项卡按时间顺序更改 我使用它们有点像旋转木马 我希望选项卡每 10 秒切换到下一个选项卡 这是一个例子 http library buffalo edu http library buffalo
  • gatsbyjs、reactjs - 为什么组件渲染两次而图像没有出现?

    我是新来的gatsbyjs并使用 v2 我有 3 个组件 加载器 标题和布局 layout js import React from react import Helmet from react helmet import StaticQu
  • 使用 Three.js 中的设备方向控件进行对象旋转

    我正在迈出使用 JavaScript 进行编码并使用 Three js 的第一步 我正在尝试 Threejs org 的这个例子 http trijs org examples misc controls deviceorientation

随机推荐

  • 无法读取 maven-resources-plugin 的工件描述符

    Stage 我正在尝试在 Eclipse 中编译 Maven 项目 Spring Tool Suite 版本 3 2 0 RELEASE 每个项目编译都会抛出这个 Could not calculate build plan Plugin
  • 如何区分不同类型的 Perl 测试,这样我就不必运行所有测试?

    我注意到 Perl 中的习惯是将所有测试放入t目录 如何将单元测试与功能测试分开 或者 为了使问题更简单 更明显 如何将快速运行的测试与运行速度慢的测试分开 当所有测试一起运行时 测试花费的时间太长 无法在开发中常规使用 这是遗憾的 我想我
  • Metro APP - BitmapImage 到 Byte[] 或从 Web 下载图像并将其转换为 Byte[] 数组

    有没有办法将 BitmapImage Windows UI Xaml Media BitmapImage 转换为 Byte 数组 我没有尝试过任何工作 另一种可能的情况 如果 BitmapImage 无法转换为字节数组 是从网络下载图像 然
  • 角度目录光滑执行

    我正在使用以下插件 http vasyabigi github io angular slick http vasyabigi github io angular slick 我也在使用 ng repeat 所以我发现它在 ng repea
  • 在宏中使用“else”

    我看过下面的代码 define QL REQUIRE condition message if condition std ostringstream ql msg stream ql msg stream lt lt message th
  • 如何以编程方式指定replyUrlsWithType

    我想设置replyUrlsWithType以编程方式在应用程序上manifest https learn microsoft com en us azure active directory develop reference app ma
  • Eclipse 在调试 java 时跳过断点

    我使用 Eclipse 已经很多年了 并且一直使用调试器 但最近我知道它可以在调试时跳过断点 我什至已经在 println 上设置了一个断点 我会看到文本出来 但不会到达断点 另外 有时我会在代码的一个区域一致地遇到断点 但在其他区域却不会
  • default(Type) 的编程等效项

    我正在使用反射来循环Type的属性并将某些类型设置为其默认值 现在 我可以切换类型并设置default Type 明确地 但我宁愿在一行中完成 是否存在与默认值等效的编程方式 如果是值类型使用激活器 CreateInstance http
  • SET NOCOUNT ON 使用情况

    灵感来自这个问题 https stackoverflow com questions 1483383 is this stored procedure thread safe or whatever the equiv is on sql
  • 如果数据包含撇号,如何插入?

    实际上 我的任务是使用 C 将 csv 文件加载到 sql server 中 所以我用逗号将其拆分 我的问题是某些字段的数据包含撇号 并且我正在触发插入查询以将数据加载到 sql 中 所以它给出了我的编码错误 using System us
  • 如何按列对文本文件进行排序并保持原始顺序

    我有一个非常大的数据文件 有 15 列 我需要根据特定列 例如第 11 列 对所有行进行排序 我在 Linux 中使用以下命令 sort k11 d myfile txt gt sortedfile 问题是排序命令不保留文件的原始顺序 例如
  • FILTER_VALIDATE 与 Preg_match。使用哪一个?

    要验证输入日期 无论是表单 URL 还是表单 您通常使用哪种技术 我一直在看PHP 过滤器 http www w3schools com php php ref filter asp但我很少在任何代码上看到它们 我平时见过preg mach
  • PHP大量内存用于SQL查询

    我在优化 Apache PHP 内存使用时偶然发现了一个奇怪的问题 基本上 当尝试绑定 MySQLi 查询的结果时 代码会崩溃 并显示错误消息 致命错误 允许的内存大小 16777216 字节耗尽 试图分配 50331646 字节 相关表格
  • 我什么时候可以激活/停用布局约束?

    我在 IB 中设置了多组约束 并且我想根据某些状态以编程方式在它们之间切换 有一个constraintsA所有出口集合均标记为从 IB 安装 并且constraintsB出口集合全部在IB中卸载 我可以通过编程方式在两组之间切换 如下所示
  • Spring Boot 中用于模块化应用程序的插件系统

    我在编译后寻找在 Spring Boot 中动态加载 jar 例如 我将 jar 放在某个文件夹中 当 Spring Boot 启动时 该文件夹中的所有 jar 将被注入到 Spring Boot 应用程序中 我不知道如何使用 Spring
  • 从powershell执行msbuild任务

    我正在关注这个博客 http sedodream com 2010 04 26 ConfigTransformationsOutsideOfWebAppBuilds aspx http sedodream com 2010 04 26 Co
  • Microsoft onedrive:无需登录即可使用 API 密钥创建文件夹

    我可以使用以下命令在 onedrive 中创建文件夹和文件Graph API 但是第一次我必须登录微软帐户 以下是我需要登录的链接 https login microsoftonline com common oauth2 v2 0 aut
  • Angular 2 (keydown.enter) 无法阻止Default()

    the event preventDefault 我使用时不起作用 keydown enter 在模板中 这是演示 https plnkr co edit GZrVt7l6BEO2uHfWFoTQ p preview https plnkr
  • Spring-data-cassandra 1.3.4 与 Cassandra 3.x 不兼容

    我尝试使用 Spring data cassandra 1 3 4 以及最新的 cassandra driver core 3 0 0 在 Cassandra 2 1 12 作为 DSE 4 8 4 的一部分 上 一切正常 因为相同的 sp
  • React 是否保证“props”对象引用保持稳定?

    最近我看到类似于以下人为示例的代码 const MyComp props gt const prevProps setPrevProps useState props if props prevProps setPrevProps prop