Skip to main content

如何更好地渲染

React.memo

当输入的外部属性 props 相同时,类组件可以使用 pureComponent 或 shouldComponentUpdate 来避免组件的渲染。

函数组件可以使用 React.memo 中来实现相同的功能。

function MyApp() {
...
};

export default React.memo(MyApp);

React.Fragments

用于组件返回多个元素,而不需要额外添加 DOM 节点。

return (
<React.Fragment>
<ChildA />
<ChildB />
<ChildC />
</React.Fragment>
)

还有一种短语法,但不支持添加 key 属性

return (
<>
<ChildA />
<ChildB />
<ChildC />
</>
)

React.lazy

允许将动态导入的组件作为常规组件进行渲染。

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

function MyApp() {
return (
<OtherComponent />
);
};

但 React.lazy 和 React.Suspense 还不能用于服务端渲染。

React.Suspense

如果父组件在渲染时,包含动态导入的模块尚未加载完成,可以使用 Suspense 组件在加载完成前展示一个 loading 指示器。

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

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

如上所示,懒加载的组件被包装在 Suspense 组件中。

React.forwardRef

因为 ref 不是一个属性,所以 ref 不会被传递,就像 key 一样。

如果你将 ref 添加到 HOC,默认情况下 ref 将引用最外层的容器组件,而不是包装的组件。

React.forwardRef 可以显式地将 ref 转发给包装的组件。

function logProps(Component) {
class LogProps extends React.Component {
componentDidUpdate(prevProps) {
console.log('old props:', prevProps);
console.log('new props:', this.props);
}

render() {
const {forwardedRef, ...rest} = this.props;

return <Component ref={forwardedRef} {...rest} />;
}
}

return React.forwardRef((props, ref) => {
return <LogProps {...props} forwardedRef={ref} />;
});
}