# 大纲
高阶大纲 (opens new window)密码:4851
# 高阶组件分类
# 属性代理
import React from 'react';
class Home extends React.Component {
render() {
return 'home';
}
}
function HOC(Component) {
return class Index extends React.Component {
render() {
return <Component {...this.props}/>;
}
};
}
export default HOC(Home);
# 反向继承
import React from 'react';
class Home extends React.Component {
render() {
return 'home';
}
}
function HOC(Component) {
// 继承
return class Index extends Component {
render() {
return <Component />;
}
};
}
export default HOC(Home);
# 怎么编写高阶组件
# 强化props
import React from 'react';
class Home extends React.Component {
componentDidMount = () => {
this.props.sayHi && this.props.sayHi();
};
render() {
return 'home';
}
}
function HOC(Component) {
return class Index extends React.Component {
sayHi = () => alert('hi');
render() {
// 增强 props
return <Component sayHi={this.sayHi} {...this.props} />;
}
};
}
export default HOC(Home);
# 控制渲染
# 渲染劫持
import React from 'react';
// 注意:不能是函数组件
class Home extends React.Component {
render() {
return <div>home</div>;
}
}
const HOC = (Component) => {
return class Index extends Component {
render() {
if (this.props.visible) {
// 反向继承,可以通过 super.render() 得到传入组件渲染的结果
return super.render();
} else {
return <div>暂无数据</div>;
}
}
};
};
class HocHome extends React.Component {
render() {
const Temp = HOC(Home);
return <Temp visible={true} />;
}
}
export default HocHome;
# 修改渲染树
import React from 'react';
class Home extends React.Component {
render() {
return <span>hello</span>;
}
}
function HOC(Component) {
return class Index extends Component {
render() {
const element = super.render();
const tempEl = <span>hello world</span>;
const newEl = React.Children.map(element.props.children, (child, index) => {
if (index === 0) return tempEl;
return child;
});
return React.cloneElement(element, element.props, newEl);
}
};
}
export default HOC(Home);
页面展示 hello。
# 组件赋能
# ref获取实例
import React from 'react';
function HOC(Component) {
return class WrapComponent extends React.Component {
constructor(props) {
super(props);
// 获取组件实例
this.node = null;
}
componentDidMount = () => {
// 获取组件状态或者执行组件方法
this.node.handleClick();
};
render() {
return <Component ref={(node) => (this.node = node)} />;
}
};
}
class Home extends React.Component {
handleClick = () => console.log('自动执行');
render() {
return 'home';
}
}
const HocHome = HOC(Home);
export default () => {
return <HocHome />;
};
# 事件监控
import React, { useEffect, useRef } from 'react';
function HOC(Component) {
return function() {
const node = useRef(null);
useEffect(() => {
const handleClick = () => console.log('点击了');
node.current.addEventListener('click', handleClick);
return () => node.current.removeEventListener('click', handleClick);
}, []);
return (
<div ref={node}>
<Component ref={node} />
</div>
);
};
}
// 这里装饰的不能是个函数
@HOC
class Home extends React.Component {
render() {
return <button>Home页面的button</button>;
}
}
export default () => {
return <Home />;
};
效果图:
# 权限拦截
import React, { useState } from 'react';
const PermissionContext = React.createContext([]);
function PermissionHoc(authorization) {
return (Component) => {
return () => {
const matchPermission = (value, list) => list.indexOf(value) >= 0;
return (
<PermissionContext.Consumer>
{(permissionList) =>
matchPermission(authorization, permissionList) ? <Component /> : <NoPermission />}
</PermissionContext.Consumer>
);
};
};
}
function NoPermission() {
return <div>您没有操作权限</div>;
}
function Add() {
return 'add';
}
function Del() {
return 'del';
}
const HocDel = PermissionHoc('del')(Del);
const HocAdd = PermissionHoc('add')(Add);
export default () => {
const [ permission ] = useState([ 'add' ]);
return (
<PermissionContext.Provider value={permission}>
<HocAdd />
<HocDel />
</PermissionContext.Provider>
);
};
展示效果