资讯专栏INFORMATION COLUMN

React - 修改children(下)

vvpvvp / 1953人阅读

摘要:倘若在之后修改对象属性,会有两种结果若在非下,不会报错,但是任何修改都是不起作用的。总结开发过程中还是用非压缩版的好,有利于及时发现问题。

在 React - 修改children(上) 中我提到了React在遍历children过程中是不允许修改其中的React Element的,这里我要做点补充,就是有个前提是:使用的React是非压缩版的,也就是说不是使用react.min.js这种,使用react.min.js则不会报错。

查看React非压缩版的源码发现,里边有许多这样的代码块,而在压缩版中是没有的。

if ("development" !== "production") {
  ......
}

举个例子 React v0.14.4 (注释被我去掉了)

react.js

var ReactElement = function (type, key, ref, self, source, owner, props) {
  var element = {
    $$typeof: REACT_ELEMENT_TYPE,
    type: type,
    key: key,
    ref: ref,
    props: props,
    _owner: owner
  };

  if ("development" !== "production") {
    ......
    Object.freeze(element.props);
    Object.freeze(element);
  }

  return element;
};

react.min.js

u = function(e, t, n, r, o, i, u) {
  var s = {
    $$typeof: a,
    type: e,
    key: t,
    ref: n,
    props: u,
    _owner: i
  };
  return s
};

对比压缩前后,由if ("development" !== "production") {} 包裹的代码块被直接strip掉了,说明压缩工具确实了得。
这里重点是看压缩前的,有两行代码很关键:

Object.freeze(element.props);
Object.freeze(element);

查看一下MDN关于Object.freeze的介绍:
The Object.freeze() method freezes an object: that is, prevents new properties from being added to it; prevents existing properties from being removed; and prevents existing properties, or their enumerability, configurability, or writability, from being changed. In essence the object is made effectively immutable. The method returns the object being frozen.
意思是说freeze防止了对象被修改,包括增删改属性。倘若在freeze之后修改对象属性,会有两种结果:
1若在非strict mode下,不会报错,但是任何修改都是不起作用的。
2若在strict mode 下,会throw TypeErrors。

看到这里可以知道,为啥在使用非压缩版的时候修改React Element时会提示报错,正是因为该对象被freeze了;相反在压缩版中因为没有freeze,所以能够成功修改,不会报错。

谈到这里再顺便提下两点:

压缩时怎么把if ("development" !== "production") {} 去掉的?
React的README提及到:

To use React in production mode, set the environment variable NODE_ENV to production. A minifier that performs dead-code elimination such as UglifyJS is recommended to completely remove the extra code present in development mode.
知道UglifyJS的朋友应该知道,UglifyJS在压缩中,如果遇到if的条件是可预计得到的常数结果,那么就会忽略掉没用的if/else分支。所以 "development" !== "production" 即 false在压缩时候就被清理掉了。
UglifyJS详细的压缩规则介绍看这里:解读UglifyJS(四)

为啥在开发环境下要使用Object.freeze(),引stackoverflow中Sean Vieira的一句话:
We use Object.freeze to freeze the router and route objects for non-production environments to ensure the immutability of these objects.

在开发过程中提示报错,在线上环境不提示,有点JAVA编译的味道,编译时校验信息,提示警告和错误,在执行中不校验。
另外,Object.freeze()运行相对较慢,所以线上去掉这个操作也是为了提高性能。
freeze vs seal vs normal 这个链接有测试的栗子。

总结:开发过程中还是用非压缩版的React好,有利于及时发现问题。
完成!!!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/78618.html

相关文章

  • React - 修改children(上)

    摘要:于是考虑通过直接对进行修改属性的方法来达到我们的目的,修改组件。运行后惊呆了,报错了意思是说属性是不能扩展的,即不能修改。于是,尝试修改代码如下运行之后,成了当然扩展的话可以根据判断或者其他要求来相应的修改属性,此处统一将所有的变为红色。 React入门,大神轻喷哈^_^下面的代码是建立在React 0.14.*版本的今天在尝试封装React component的时候碰到了几个问题,猜...

    EsgynChina 评论0 收藏0
  • 前端开发中,滑动展现日志麻烦?这个组件来帮你

    摘要:使用者需要做的,就是完成回调函数里的逻辑即可,十分简单。如果你需要异步生成,你需要设置参数为元素展现时的回调函数,接收和作为参数。多次展现时,是否每次都触发回调函数组件里监听滑动事件时,用了。 showImg(https://segmentfault.com/img/bVbloJf?w=620&h=480); 写在前面 在这个数据无比重要的时代,用户在网页上面的一系列操作,都需要用数据...

    Clect 评论0 收藏0
  • React + Ramda: 函数式编程尝鲜

    摘要:每当的值改变后,我们只需要重新调用方法即可现在,让我们来实现一个类似风格的归约函数,以不断的递增。归约函数是不允许修改当前状态的,所有最简单的实现方式就是。 原文:Functional Components with React stateless functions and Ramda 阅读本文需要的知识储备: 函数式编程基本概念(组合、柯里化、透镜) React 基本知识(组件、...

    tomener 评论0 收藏0
  • 精益 React 学习指南 (Lean React)- 4.2 react patterns

    摘要:另外一点是组件应该尽量保证独立性,避免和外部的耦合,使用全局事件造成了和外部事件的耦合。明确的职责分配也增加了应用的确定性明确只有组件能够知道状态数据,且是对应部分的数据。 书籍完整目录 4.2 react patterns 修改 Props Immutable data representation 确定性 在 getInitialState 中使用 props 私有状态和...

    Berwin 评论0 收藏0
  • With TypeScript 2.8+ :更好的 React 组件开发模式

    摘要:近两年来一直在关注开发,最近也开始全面应用。首先,我们从无状态组件开始。渲染回调模式有一种重用组件逻辑的设计方式是把组件的写成渲染回调函数或者暴露一个函数属性出来。最后,我们将这个回调函数的参数声明为一个独立的类型。 近两年来一直在关注 React 开发,最近也开始全面应用 TypeScript 。国内有很多讲解 React 和 TypeScript 的教程,但如何将 TypeScri...

    simon_chen 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<