如何更好地渲染
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} />;
});
}