React16.6带来的新特性

最近(2018-10-23)React官方发布了16.6版本,开放了一堆新的功能,而这其中的一些新功能,代表这未来的React开发方式,让我们来一起窥探未来吧。

lazy

最让人期待的功能肯定就是lazy功能了,配合发布了一个Suspense组件,也就是最开始命名为Placeholder的组件,用来配合render方法内部的异步操作的,让我们先来看一下lazy的用法

import React, {lazy, Suspense} from 'react';
const OtherComponent = lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <OtherComponent />
    </Suspense>
  );
}
复制代码

做过code-splitting的同学能闻到熟悉的味道。以前我们要用第三方包或者自己处理异步过程,现在,React原生支持啦,而且你可以把异步的过程直接扔到render方法里面,就跟写普通组件一样,而且可以方便得通过Suspense组件来提供fallback

然而这并不仅仅Suspense的唯一用处,事实上这次React正式开放Suspense组件代表着所有异步的操作都可以在render方法里面做了,其实我很意外,我以为正式开放肯定要等到17版本

那么异步操作还能做啥?如果同学们看过年初Dan在冰岛的分享,应该就知道,Suspense能够让我们加载数据的操作变得异常简单。没看过的同学可以看这里,现在npm上也有一个包提供数据加载的功能了,simple-cache-provider,但是现在还不要在正式环境使用他哦。

关于这部分如何实现的,我会在之后的源码分析上详细讲解,有兴趣的同学可以关注我。

React.memo

ClassComponent可以通过继承类PureComponent或者实现shouldComponentUpdate来主动判断组件是否需要重新渲染,以此来提高性能,但是FunctionalComponent到目前为止没有类似的功能。

所以今天React发布了React.memo方法,来实现类似PureComponent的功能,即浅比较props是否有变化,如果没有变化,就不重新渲染当前组件

const FunctionalComponent = React.memo((props) => {
  // only render if props change
})
复制代码

static contextType

在React16.3中提供了我们一个标准的用于替代老的context的API,也就是React.createContext,然后通过context.Providercontext.Consumer来传递值,这种方式消除了老的context API性能低下的问题,这个问题我在之前也有详细分析,感兴趣的同学可以看这里,而且老的API代码量很多,所以下个大版本React会移除老的API。

但是在让生态插件升级到新的API的过程中,有人提出在ClassComponent中用新的API很麻烦(???没感觉啊),所以React提供了一种在ClassComponent中使用新API的方法

import React, { Component } from 'react';

const context = React.createContext('defaultValue')


const ProviderComp = ({ children }) => (
  <context.Provider value="provider">
    {children}
  </context.Provider>
)

class ConsumerComp extends Component {
  static contextType = context

  componentDidMount() {
    console.log(this.context)
  }

  render() {
    return (
      <p>{this.context}</p>
    )
  }
}

class App extends Component {
  render() {
    return (
      <ProviderComp>
        <ConsumerComp />
      </ProviderComp>
    );
  }
}
复制代码

通过声明static contextType = context,让ClassComponent可以订阅最近的一个context provider注意这里contextType是固定声明,换成别的名字都不行。如果ConsumerComp不在Provider的子树中,那么会使用defaultValue

class App extends Component {
  render() {
    return (
      <>
        <ProviderComp />
        <ConsumerComp />  // show default value
      </>
    );
  }
}
复制代码

这也是为了提高React的整体性能,移除老旧API做努力。

static getDerivedStateFromError()

在发布Error Boundaries的时候,React提供了一个新的生命周期方法componentDidCatch,在捕获到错误的时候会触发,你可以在里面修改state以显示错误提醒的UI,或者将错误信息发送给服务端进行log用于后期分析。但是这里有个问题,就是在捕获到错误的瞬间,React会在这次渲染周期中将这个组件渲染为null,这就有可能导致他的父组件设置他上面的ref获得null而导致一些问题,所以现在提供了这个方法。

这个方法跟getDerivedStateFromProps类似,唯一的区别是他只有在出现错误的时候才触发,他相对于componentDidCatch的优势是在当前的渲染周期中就可以修改state,以在当前渲染就可以出现错误的UI,而不需要一个null的中间态。

而这个方法的出现,也意味着以后出现错误的时候,修改state应该放在这里去做,而后续收集错误信息之类的放到componentDidCatch里面。

StrictMode下的新提醒

StrictMode是用来提醒开发者用了即将被废弃的API的,像componentWillMount这些声明周期都会提醒,这次新加了两个API的提醒,ReactDOM.findDOMNode(),和老的context api

也代表着这两个下个大版本肯定会被移除。所以兄弟们还不赶紧更新!

知识共享署名 4.0 国际许可协议,转载请保留出处:前端123学堂 » React16.6带来的新特性

赞 (1) 打赏

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

如果对您有帮助,别忘了打赏一下宝宝哦!

支付宝扫一扫打赏

微信扫一扫打赏