美文网首页React or React-Native
React 16.6.X版本的更新功能

React 16.6.X版本的更新功能

作者: 吴佳浩 | 来源:发表于2018-12-23 16:47 被阅读0次

    React发布了16.6版本,在此版本中带来了一些非常有用的新特性。主要的新特性包括:

    React.lazy()

    React.memo()

    static contextType()

    static getDerivedStateFromError()

    StrictMode下的新提醒

    下面一起来看看吧

    lazy

    新版本的更新让人期待的功能之一肯定就是lazy功能啦,搭配发布了一个Suspense组件,用来配合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 (
                <div>
                    <ProviderComp />
                    <ConsumerComp />
                // show default value      
                </div>
            );
        }
    }
    

    这也是为了提高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

    相关文章

      网友评论

        本文标题:React 16.6.X版本的更新功能

        本文链接:https://www.haomeiwen.com/subject/dzclkqtx.html