HOC 其实有两种模式,
一种是『属性代理』
属性代理大家很熟悉了,也是大家最常用的一种 HOC 形式,主要是用于修改 props,抽象 state, 调取 refs 等等,就不多赘述了,以上这些 React Hooks 都能完成的更出色.
function HOC(WrappedComponent) {
return class CHOC extends React.Component {
render() {
return <WrappedComponent {...this.props} />;
}
};
}
还有一种模式叫『反向继承』
function HOC(WrappedComponent) {
return class Enhancer extends WrappedComponent {
render() {
return super.render();
}
};
}
此模式与『属性代理』不同之处是,HOC 返回的新组件其实是继承了原始组件的,当然这在 React 的理念中有点反模式,因为大家一直强调的是『组合优于继承』
由于是继承了原始组件,所以『反向继承』中可以做一些更『出格的操作』,我们称这一系列的操作为『渲染劫持』
比如一个渲染劫持的例子是修改 elements tree, 比如我们想把一个 input 组件的 value 修改为’world’
const HOC = (Component) => {
return class EnhancerComponent extends Component {
static displayName = "UserGetComponent";
render() {
const elementsTree = super.render();
let newProps = {};
if (elementsTree && elementsTree.type === "input") {
newProps = { value: "world" };
}
const props = Object.assign({}, elementsTree.props, newProps);
const newElementsTree = React.cloneElement(
elementsTree,
props,
elementsTree.props.children
);
return newElementsTree;
}
};
};
这种情况下,所有被 HOC 修饰过的组件,如果是一个 input 组件,那么 value 全部会被渲染为 world