React@16.3 ContentAPI

358 阅读4分钟

React@16.3 ContentAPI

前言

有了解过React16版本特性的都清楚。React在该版本中引入了一个全新的API(React.createContext)用来替换旧的ContentAPI。本文主要带大家了解下新旧API的区别,以及如何使用新的API。

为什么要替换?(旧的API有什么问题?)

新API替换旧API在官方文档中有这样一段说明:

The problem is, if a context value provided by component changes, descendants that use that value won’t update if an intermediate parent returns false from shouldComponentUpdate. This is totally out of control of the components using context, so there’s basically no way to reliably update the context.

翻译过来的意思就是,当context的值更新的时候,无法确保子节点的值也会更新。原因是content自上而下更新的过程可能会被生命周期函数shouldComponentUpdate阻止。

什么是Context?

众所周知,React的一个核心思想是单向数据流。在开发过程中深层的子节点需要使用顶级父节点的数据或者方法,根据单向数据流的思想需要通过props一层层往下传。当组件嵌套较深的时候,这样的写法很容易让人抓狂。Context API的出现就是为了解决这一问题。Context提供了一个无需为每层组件手动添加props,就能在组件树之间进行数据传递的方法

如何使用Context?

本小节我们将通过一个例子来展示如何去使用Context。举例:我们在父节点通过"theme"属性手动去调整子节点中按钮的样式。

不使用Context的代码如下:

demo1

在上面的例子中,ToolBar组件接收一个额外的"theme"属性,然后传递给ThemedButton组件。对于它自己"theme"这个属性并没有任何作用。试想一下如果组件的层级不止三级而是更多级,那是不是就得去写很多没有什么意义的代码,这显然是一件非常麻烦的事情。

下面我们先来看看使用Context的代码。

demo2

上面的代码先抛开Context的使用,从代码中我们可以清楚的看到ToolBar组件并没有接收theme属性,但是在ThemedButton组件中却可以去使用顶级组卷传递的值,是不是觉得很神奇?使用Context的优点是无论组件层级有多深,任何组件都能读取到根节点的属性值

Context API

React.createContext

demo3

创建一个Context对象。当页面渲染一个订阅了这个Context对象的组件,这个组件就会从组件树中离自己最近的那个匹配的Provider中读取到当前的Context值。当Context的值为空的时候,defaultValue值才会生效

Context.Provider

每一个Context对象都会返回一个Provider React组件,它允许消费组件订阅context的变化。

消费组件的两种实现方式

  • Class.contextType 这种方法是将React.createContext返回的对象挂载在class的contentType上。在组件内容可以使用this.context来消费最近的Context上的那个值,可以在任意的生命周期和render中访问该值。

demo4

  • Context.Consumer

这种方法实现的代码请看例1的代码。这种实现方法的特点是需要一个函数作为子元素。这个函数接收当前的context的值并返回一个 React 节点。传递给函数的 value 值等价于组件树上方离这个 context 最近的 Provider 提供的 value 值。如果没有对应的 Provider,value 参数等同于传递给 createContext() 的 defaultValue。

什么时候使用Context API

在前面我们what、why、how三个角度介绍了Context API,本小节我们来讲讲什么时候该使用Context API(when)

从前面的代码中我们应该很容易看出来,使用Context带来的一个非常大的问题就是它会让组件的复用性变差。所以我们要谨慎使用Context。个人建议是当应用的使用场景在很多不同层级的组件需要访问一些相同的数据(例如:locale、theme、缓存数据)时才考虑使用。

参考文档

React.createContext()

React@16.3 全新的Context API进阶教程