React 16.3(.0-alpha) 新特性

React 16.3-alpha 于不久前推至 npmjs,已经可以用在项目中了,你最关心哪些变化呢?

2018 年 2 月 5 日更新 —— 之前我误解了 createContext 的一些行为,所以更新了这一节的内容,主要为了反映出工厂方法的一些行为。

全新的 context API

Context API 一直很神秘 —— 本来它是一个官方推出的、文档化的 API,但开发者们又提醒我们尽量不要用这个 API,因为这个 API 还没完全确定下来,以后可能会再作修改,而且文档尚不完备。不过,是时候让它发光发热了,RFC 流程已经通过了,新的 API 代码也已经合并了,用起来也更加顺手了。至少在状态管理这方面,如果项目并不复杂的话,完全可以不用 Redux 和 MobX。

新的 API 方法主要体现在 React.createContext() 上,调用之后会创建两个组件:

调用 React.createContext() 创建一个上下文(context)对象

这个工厂方法返回的对象包含“Provider”和“Consumer”两个属性,即上文提到的两个组件。

Provider 组件用来为其所有子层级组件提供数据,示例如下:

在上图中,将需要接受数据的组件放在 ThemeContext.Provider 下,设置其 value 属性,用来存放需要传递的数据。当然这个 value 也可以是动态变化的(用 this.setState)。

接下来设置 Consumer 组件:

如果你把 Consumer 组件放在了 Provider 组件的外部(不在它的下面),其值会默认使用调用 createContext 时传入的值。

PS:

  • Consumer 组件只能获取到对应的 Context 里设置的数据,即使新创建了一个 Context,传入和已有的 Context 一样的参数,不属于这个 Context 的 Consumer 是获取不到它设置的数据的。所以,不妨把 Context 看成一个组件,相同用途的 Context 只创建一次,再根据需要作导入导出(export/import)。
  • 新的写法采用的是”方法即子组件模式”(即 function as child pattern,有时也称作 render prop 模式),如果你对这种模式很陌生,可以参考这里
  • 新的 API 不用再通过 prop-types 设置 contextProps 了。

Consumer 下的 context 参数对应了 Provider 组件里设置的 value 属性,修改 Provider 里设置的数据会导致对应的 Consumer 下的组件重新渲染。

新的生命周期方法

另一个促使其进入 alpha 阶段的 RFC 和某些生命周期方法的废除有关,同时也还会引进一个(译者注:其实还有另外三个方法 —— 要废除的生命周期方法前面加个“UNSAFE_”前缀构成的新方法)新的方法。

这些改变旨在引导开发者作出最佳实践(将被废除的这些生命周期方法颇具坑点,具体可以参考我写的另一篇文章),这也有益于适应将来全面开放的异步渲染模式(这也是 React 16 “Fiber” 的首要目标)。

即将被废除的方法如下:

  • componentWillMount —— 即将废除,使用 componentDidMount 作为替代
  • componentWillUpdate —— 即将废除,使用 componentDidUpdate 作为替代
  • componentWillReceiveProps —— 即将废除,使用新引进的方法 static getDerivedStateFromProps

不要瞎慌,这些方法现在都可以正常使用,不影响,到 16.4 版本才会正式打上“已废除”的标记,真正移除可能要到 17.0 以后。

Dan 表示,“故事还长,大家别慌”,然而仍有群众表示恐慌。

如果你开启了 StrictMode 或是 AsyncMode,它只会提示你方法已经废除了,不想看到这些提示信息可以使用如下方法替代:

  • UNSAFE_componentWillMount
  • UNSAFE_componentWillReceiveProps
  • UNSAFE_componentWillUpdate

静态方法:getDerivedStateFromProps

既然 componentWillReceiveProps 要被废除了,那么,还有其他的方法能根据 prop 的改变更新 state 吗(不推荐使用这种开发模式)?这里就要用到新引进的那个静态方法了。

这里说的静态和其他语言的概念是一样的,它是存在于类自身的方法,不依赖实例的创建。与一般的类方法的区别在于它不能访问 this 关键字,还有就是方法前面有个 static 修饰符。

嗯,那行,但是有一个问题,既然访问不到 this 了,那还怎么用 this.setState 来更新状态呢?答案是,“压根就不需要用这个方法了”,你只需要返回新的状态就行了,直接 return 出去,不需要用方法去设置。如果不需要更新状态,返回 null 就行了:

此外,返回值的机制和使用 setState 的机制是类似的 —— 你只需要返回发生改变的那部分状态,其他的值会保留。

敲黑板:

说了这么多,还是要提醒下各位记得在构造器里初始化一下 state(在构造器里或者用 class field),不然就会报上面的错误。


这个方法在组件首次挂载和将要重新渲染的时候会调用,所以你可以在它里面初始化状态,来代替在构造函数里面初始化。


如果同时定义了 getDerivedStateFromPropscomponentWillReceiveProps,只有 getDerivedStateFromProps 会被调用,同时 React 还会打印出警告信息。


还有一种情况就是,当状态发生变化的时候需要执行回调,这时候你就可以用 componentDidUpdate


如果你觉得 static 不够优雅,你可以用下面这种方式定义,效果是一样的:

StrictMode

Strict mode 是新加入的组件,旨在引导你遵循最佳实践。把需要进行约束的组件簇放在它的下面就完事了:

完全一变相的 'use strict'

如果其下的组件不小心用了上文提到的要废除的生命周期方法,控制台会打印出错误信息(开发环境下):

错误信息提供的链接地址目前指向的是一个 RFC issue,也是因为生命周期方法被废除导致的。

AsyncMode

为了配合 StrictMode,异步组件支持现在重新命名为 React.unsafe_AsyncMode,它也会引发 StrictMode 的警告信息。

有关异步组件的使用可以参考以下博文:

新版 React 开发工具

新版本的开发工具也已经跟进,可以识别新加入的组件了。

但是 Chrome 上的插件还没有更新,还要等一段时间,所以 debug 的时候会看到很有趣的东西:

React. __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(译者注:红头组件,用了你就怕是要被炒鱿鱼了)表示不服。

Firefox 用户就有福了,完全支持:

可以看到 AsyncMode 组件可以直接被识别。

后日谈

总之呢,这还只是 alpha 版本,等稳定版本出来的时候可能会有点改动。根据 Dan 的说法,稳定版差不多下周就出:

讲道理,这不已经过了一个星期吗?


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

[译] React 16.3(.0-alpha) 新特性的更多相关文章

  1. php5.3到php7.0.x新特性介绍

    <?php /*php5.3*/ echo '<hr>'; const MYTT = 'aaa'; #print_r(get_defined_constants()); /* 5.4 ...

  2. [PHP] 从PHP 5.6.x 移植到 PHP 7.0.x新特性

    从PHP 5.6.x 移植到 PHP 7.0.x 新特性: 1.标量类型声明 字符串(string), 整数 (int), 浮点数 (float), 布尔值 (bool),callable,array ...

  3. paip.php 5.0 5.3 5.4 5.5 -6.0的新特性总结与比较

    paip.php 5.0 5.3 5.4  5.5 -6.0的新特性总结与比较 PHP5的新特性 2 · 对象的参照过渡是默认的(default) 3 · 引入访问属性的限制 3 · 引入访问方法的限 ...

  4. NodeJS 框架 Express 从 3.0升级至4.0的新特性

    NodeJS 框架 Express 从 3.0升级至4.0的新特性 [原文地址:√https://scotch.io/bar-talk/expressjs-4-0-new-features-and-u ...

  5. 相比于python2.6,python3.0的新特性。

    这篇文章主要介绍了相比于python2.6,python3.0的新特性.更详细的介绍请参见python3.0的文档. Common Stumbling Blocks 本段简单的列出容易使人出错的变动. ...

  6. MySQL 8.0 InnoDB新特性

    MySQL 8.0 InnoDB新特性 1.数据字典全部采用InnoDB引擎存储,支持DDL原子性.crash safe,metadata管理更完善 2.快速在线加新列(腾讯互娱DBA团队贡献) 3. ...

  7. Atitit jquery  1.4--v1.11  v1.12  v2.0  3.0 的新特性

    Atitit jquery  1.4--v1.11  v1.12  v2.0  3.0 的新特性 1.1. Jquery1.12  jQuery 2.2 和 1.12 新版本发布 - OPEN资讯.h ...

  8. React 16.3.0 发布,构建用户界面的 JavaScript 库

    React 16.3.0 已发布,React 是 Facebook 推出的一个为数据提供渲染为 HTML 视图,用来构建用户界面的开源 JavaScript 库. React 视图通常采用包含以自定义 ...

  9. servlet3.0 的新特性之二注解代替了web.xml配置文件

    servlet3.0 的新特性: 注解代替了 web.xml 文件 支持了对异步的处理 对上传文件的支持 1.注解代替了配置文件 1.删除了web.xml 文件 2. 在Servlet类上添加@Web ...

  10. C# 6.0/7.0 的新特性

    转眼C#语言都已经迭代到7.0版本了,很多小伙伴都已经把C# 7.0 的新特性应用到代码中了,想想自己连6.0的新特性都还很少使用,今天特意搜集了一下6.0和7.0的一些新特性,记录一下,方便查阅. ...

随机推荐

  1. Pytest系列(10) - firture 传参数 request的详细使用

    如果你还想从头学起Pytest,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1690628.html 前言 为了提高复用性,我们在写测试 ...

  2. Scratch 第1课 让小猫动起来

    素材下载 链接:https://pan.baidu.com/s/1qX0T2B_zczcLaCCpiRrsnA提取码:xfp8

  3. Vulnhub DC-2靶机渗透

    信息搜集 nmap扫描端口 nmap -sV 192.168.146.140 -p1-10000 开了80端口,那就直接访问一下把.(7744端口是ssh端口,之后会用到) 输入ip,发现url处变成 ...

  4. Ubuntu 修改$PS1 自定义命令提示符

    文章更新于:2020-03-25 文章目录 一.自定义命令提示符 1.可修改的是那部分? 2.修改 $PS1 变量 3.$PS1 变量格式 4.如何修改背景颜色 5.修改字体 二.Enjoy! 一.自 ...

  5. linux被当矿机排查案例

    1.发现服务器变的特别卡,正常服务运行很慢. 到服务器上查询一番发现top下发现     bashd的进程占用100%CPU了. find /-name bashd* //第一次查询文件占用目录kil ...

  6. 基于 Jepsen 来发现几个 Raft 实现中的一致性问题(2)

    Nebula Graph 是一个高性能.高可用.强一致的分布式图数据库.由于 Nebula Graph 采用的是存储计算分离架构,在存储层实际只是暴露了简单的 kv 接口,采用 RocksDB 作为状 ...

  7. 第一天总结(while计数器+成绩大小+获取时间+猜拳大小)

    #*_* coding:utf-8 *_*# while 先有一个计数器 input = 0# input = input('输入数字')while input < 5: input= inpu ...

  8. MySQL中的事务和MVCC

    本篇博客参考掘金小册--MySQL 是怎样运行的:从根儿上理解 MySQL 以及极客时间--MySQL实战45讲. 虽然我们不是DBA,可能对数据库没那么了解,但是对于数据库中的索引.事务.锁,我们还 ...

  9. matplotlib BlendedAffine2D 和 CompositeAffine2D

    2020-04-11 10:00:01 --Edit by yangrayBlendedAffine2D 继承于Affine2DBase,支持x和y方向使用不同的仿射变换策略.(自译:混合仿射变换)C ...

  10. matplotlib TransformWrapper

    2020-04-09 23:26:53 --Edit by yangray TransformWrapper 是Transform的子类, 支持在运行中替掉一个变换(可以是不同类型, 但维度必须相同) ...