有状态组件

由于灵巧组件面向业务,所以相对于展示组件来说,其功能更为丰富、复杂性更高,而复用度更低。展示组件专注于组件本身特性灵巧组件更专注于组合组件

容器组件

容器组件几乎没有复用性,它主要用在两个方面:拉取数据与组合组件

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 属性由于被高阶组件包裹了一次,所以需要进行特殊处理才能获取。