React类中的成员变量通过引用“共享”

2023-11-23

当我创建一个反应类的多个实例(通过在同一个类上使用 React.createElement )时,一些成员变量在实例之间共享(数组和对象是共享的,字符串和布尔值等不是共享的)。

对我来说,这感觉可怕、可怕、错误。这是一个错误还是有其他方法可以做我想做的事情?

请看一看:http://jsbin.com/kanayiguxu/1/edit?html,js,控制台,输出


您应该做的是在组件上设置状态,而不是将状态作为 React 组件上的任意属性。

所以不要这样做:

var MyComponent = React.createClass({
  myArray: [1, 2, 3],
  componentWillMount() {
    this.myArray.push(this.myArray.length + 1);
  },
  render() {
    return (
      <span>{this.myArray.length}</span>
    );
  }
});

你应该这样做:

var MyComponent = React.createClass({
  getInitialState() {
    return {
      myArray: [1, 2, 3]
    };
  },
  componentWillMount() {
    this.setState(state => {
      state.myArray.push(state.myArray.length + 1);
      return state;
    });
  },
  render() {
    return (
      <span>{this.myArray.length}</span>
    );
  }
});

原因是所有组件状态和数据都应驻留在this.state and this.props它由 React 控制和处理。

使用 props 和 state 的好处是,React 会知道它们何时发生变化,并从中知道何时需要重新渲染组件。如果您将状态存储为任意属性或全局变量,React 将不知道这些更改何时发生,并且无法为您重新渲染。

您所看到的行为的原因是组件的每个实例都使用您提供的对象React.createClass()作为它的原型。所以该组件的所有实例都有一个myArray属性,但它位于原型链上,因此由所有实例共享。

如果你真的想要这样的东西并且你想避免this.state,你应该使用类似的东西componentWillMount并在该方法内部,将属性分配给this。这将确保此类数据仅位于该特定实例上,而不位于原型链上。

EDIT

为了进一步澄清,最好知道该对象传递给React.createClass()不是原型上的实际对象。 React 所做的是迭代该对象上的所有属性,并将它们复制到 React 元素对象的原型上。这可以通过这个例子来说明:

var obj = {
  myArray: [1, 2, 3],
  title: 'My title',
  componentWillMount() {
    this.myArray.push(this.myArray.length + 1);
  },
  render() {
    return (
      <span>{this.myArray.length}</span>
    );
  }
}

var MyComponent = React.createClass(obj);

// This doesn't change the component, since 'obj' isn't used anymore
// by React, it has already copied all properties.
obj.title = 'New title';

// This however affects the component, because the reference to the array
// was copied to the component prototype, and any changes to what the 
// reference points to will affect everyone who has access to it.
obj.myArray.push(666);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React类中的成员变量通过引用“共享” 的相关文章

随机推荐

  • 使用视觉状态管理器设置前景时出现问题

    我有一个 WPF 应用程序 我正在尝试使用 Net v4 视觉状态管理器设置 TextBox 的样式 具体来说 我尝试设置 MouseOver 状态的前景和背景的颜色 正在发生的情况是 虽然背景和边框发生了完美的变化 但前景却没有 如果我使
  • 循环声音 flash as3 的首选方法

    我在 Flash AS3 中循环播放声音时遇到一些问题 因为当我告诉声音循环时 我在音频的结尾 开始处出现轻微的延迟 音频剪辑正确 并且可以在车库乐队上无间隙地播放 我知道 Flash 中普遍存在声音问题 编码错误以及 SOUND COMP
  • 如何将文件发送到浏览器进行下载?

    当客户端请求文件时 我使用以下代码发送它 public static Result download String file File file getRealFile file return Ok file 但我发现浏览器不会下载它 而是
  • 如何知道使用了什么 JAXB 实现?

    我使用 MOXy 作为 JAXB 实现 但不知何故我想在某些管理屏幕上 动态 显示实现名称 例如 Moxy 和版本号 我如何从 JAXB 检索该信息 Cheers 您可以执行类似以下操作来找出正在使用的 JAXB impl import j
  • 对回形针中的视频/图像使用单个附件

    我正在使用回形针上传文件 视频和图像 视频和图像使用相同的附件 源 class Media lt ActiveRecord Base belongs to memory validates attachment presence sourc
  • 分析 wav 并绘制图表

    我正在尝试从 wav 文件中打印出波形 但我有点不知道我应该采取多长的样本 this is what I would love to archieve without the colors 因此 为了读取我的数据 我使用以下代码 first
  • 使用 new 初始化 C# 数组与使用文字初始化

    简单的简短问题 到底有什么区别 int intarray new int 2 1 2 and int intarray2 4 5 6 就像 新 到底做什么 你真的需要它吗 我猜它只是分配内存 或者什么 抱歉 我对 C 完全陌生 在学习过程中
  • Django 空字段后备

    我有一个保存用户地址的模型 这个模型必须有first name and last name字段 因为人们想为收件人设置地址 例如他的公司等 我想要实现的是 If the first name last name地址中的字段已填写 仅返回该字
  • Python - 等待变量更改

    我有一个 Python 脚本 可以打开 Twitter API 的 websocket 然后等待 当事件通过 amq 传递给脚本时 我需要打开一个新的 websocket 连接并立即地新连接注册后立即关闭旧连接 它看起来像这样 stream
  • Python argparse:组合“choices”、“nargs”和“default”时类型不一致

    我有以下 python 程序 usr bin env python import argparse parser argparse ArgumentParser parser add argument arg choices foo bar
  • 使用javascript获取div内第一个输入的id

    HTML div div
  • Rails CSRF 保护 + Angular.js:protect_from_forgery 让我在 POST 上注销

    If the protect from forgeryapplication controller 中提到了选项 然后我可以登录并执行任何 GET 请求 但在第一个 POST 请求时 Rails 会重置会话 从而使我退出 我转动了prote
  • 如何将多个 .net 程序集合并为一个程序集?

    我有一个包含大约 10 个程序集的 net 应用程序 如果将它们作为一个组件组合在一起 那就太好了 我该怎么做 我猜想类似于 Java 应用程序的 jar 文件 Try ILMerge NuGet包here
  • 如何使用 Cocoa 和 Python (PyObjC) 创建状态栏项目?

    我在 XCode 中创建了一个全新的项目 并在我的 AppDelegate py 文件中包含以下内容 from Foundation import from AppKit import class MyApplicationAppDeleg
  • 使用 POST 请求 golang 上传文件

    我是 golang 新手 我正在尝试编写一个函数 为我正在编写的机器人上传带有发布请求的文件到电报 我尝试过使用这段代码 但我从电报中得到的错误是Bad Request there is no photo in the request 我在
  • OpenCV:从USB摄像头捕获的黑色图像

    我正在尝试使用 opencv 从 USB 摄像头捕获图像帧 然而我总是得到一个黑框 我已经阅读了很多有关此问题的帖子并尝试了所有建议 但对我来说没有任何作用 我开始使用这里讨论的代码 http opencv users 1802565 n2
  • 在 LinearLayout 中设置 textview 的宽度

    我正在使用列表视图的标题 ListView 标题有三列 说a b c 我使用两个 LinearLayouts 来设计 ListView 标题 如下所示
  • 新渲染元素的动画,但页面加载时不动画

    我订阅了 Firebase 实时数据库 这样当我向它提交某些内容时 它会立即在视图中呈现 而不需要 jQuery 或 ajax 我想对这些元素的渲染进行动画处理 这样当一个新元素添加到 DOM 时 它的div s background co
  • Swift 中的十六进制/二进制字符串转换

    Python 有两个非常有用的库方法 binascii a2b hex keyStr 和 binascii hexlify keyBytes 我在 Swift 中一直在努力解决它们 Swift 中有什么现成的东西吗 如果没有 又该如何实施呢
  • React类中的成员变量通过引用“共享”

    当我创建一个反应类的多个实例 通过在同一个类上使用 React createElement 时 一些成员变量在实例之间共享 数组和对象是共享的 字符串和布尔值等不是共享的 对我来说 这感觉可怕 可怕 错误 这是一个错误还是有其他方法可以做我