有状态组件
由于灵巧组件面向业务,所以相对于展示组件来说,其功能更为丰富、复杂性更高,而复用度更低。展示组件专注于组件本身特性,灵巧组件更专注于组合组件。
容器组件
容器组件几乎没有复用性,它主要用在两个方面:拉取数据与组合组件。
class CardListContainer extends React.Component {
state = { cards: [] };
async componentDidMount() {
const response = await fetch("/api/cards");
this.setState({ cards: response });
}
render() {
return <CardList cards={this.state.cards} />;
}
}高阶组件
React 的官方文档将高阶组件称为 React 中复用组件逻辑的高级技术。高阶组件本身并不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。简而言之,高阶组件的参数是组件,返回值为新组件的函数。
抽取公共逻辑
用一个常见的例子来说,就是登录态的判断。
还有一个非常经典的场景就是页面埋点统计。
链式调用
由于高阶组件返回的是一个新的组件,所以链式调用是默认支持的。
// 函数调用方式
class RawUserPage extends React.Component {
...
}
const UserPage = checkLogin(PV('用户页面')(RawUserPage))
// 装饰器调用方式
@checkLogin
@PV('用户页面')
class UserPage extends React.Component {
...
}
渲染劫持
渲染劫持可以通过控制 render 函数修改输出内容,常见的场景是显示加载元素
function withLoading(WrappedComponent) {
return class extends WrappedComponent {
render() {
if (this.props.isLoading) {
return <Loading />;
} else {
return super.render();
}
}
};
}缺点
- 丢失静态函数。由于被包裹了一层,所以静态函数在外层是无法获取的。解决方案:
hoist-non-react-statics - refs 属性不能透传。ref 属性由于被高阶组件包裹了一次,所以需要进行特殊处理才能获取。