all articles

React 16.6 new feature memo, lazy, suspense

2018-11-15 @sunderls

js react

https://reactjs.org/blog/2018/10/23/react-v-16-6.html

react 16.6 发布了,新增了一些新特性。

平时一直很忙,没有时间看,现在终于有点时间来看看有些什么新东西。

1. React.memo

React.memo用来让 pure component 避免重复渲染。 简单的说是,用React.memo可以让 pure component 变成 PureComponent.

const MyComponent = React.memo(function MyComponent(props) {
  /* only rerenders if props change */
});

相比之下 PureComponent 唯一有的好处就是,可以有自己的 state 和 method 了。一般情况下这个就够用了。

但是为啥这个 memo 不是 default 呢?

感觉上 pure component 都挺适合。原因是 memo 也有成本,比如某些快速不断更新的时候,如果 props 内容很多, shallow 比较就会耗去更多时间,与其如此,还不如 rerender。这更多的是一种可选的 balance。

https://twitter.com/dan_abramov/status/1054930594143109120

3. React.lazy

React 把 lazy load 变成了一等公民。

const OtherComponent = React.lazy(() => import("./OtherComponent"));

function MyComponent() {
  return (
    <div>
      <OtherComponent />
    </div>
  );
}

很容易理解,这个感觉原理上并不难,要自己做的话,大概维护一个 loaded flag 就行了

(以下代码只是想法,没有 run 过)

class Lazy extends PureComponent {
    constructor() {
        this.props.init().then((component) => {
            this.component = component;
            this.setState({
                loaded: true;
            }
        });
    }

    state = {
        loaded: false
    }

    render() {
        const component = this.component;
        return this.state.loaded ? <component/> : null;
    }
}

const lazy = (init) => () => <Lazy init={init}/>

3. React.Suspense

Suspense 用来添加一个 placeholder,在 lazy 的 component 加载之前显示。

const OtherComponent = React.lazy(() => import("./OtherComponent"));
const AnotherComponent = React.lazy(() => import("./AnotherComponent"));

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <section>
          <OtherComponent />
          <AnotherComponent />
        </section>
      </Suspense>
    </div>
  );
}

感觉Suspense应该就是一个 context provider, 传递给了 lazy 一个fallback element。

这样OtherComponentAnotherComponent在显示之前就可以显示 fallback 的内容。

4. 总结。

感觉东西挺新鲜,时间上并不是。是其他的一些好的想法被 react 官方采用了。比如Suspenselazy,没有他们一样可以用rect-loadable 实现。

个人并不太觉得 lazySuspense听起来有多酷炫。首先,lazySuspence都是为了性能优化而来的。 既然是颈上添花,也许没有必要搞的这么复杂。

对于这种东西,更加友好的方式是,保持 sync 的思考,然后可以选择 lazy 也可以选择不 lazy。annatation 更加适合。

比如

@lazy
class Component {}

当我们不想要的时候,只需要删除 annatator 就行了。