React 高阶组件HOC — 逻辑复用的”增强壳”
· 3 min read

高阶函数与高阶组件
在解释什么是高阶组件之前,可以先了解一下什么是 高阶函数,因为它们的概念非常相似,下面是高阶函数的定义:
如果一个函数接受一个或多个函数作为参数或者返回一个函数就可称之为高阶函数。
下面就是一个简单的高阶函数:
function withGreeting(greeting = () => {}) {
return greeting;
}
高阶组件的定义和高阶函数非常相似:
如果一个函数接受一个或多个组件作为参数并且返回一个组件就可称之为高阶组件。
下面就是一个简单的高阶组件:
function HigherOrderComponent(WrappedComponent) {
return <WrappedComponent />;
}
Examples
1. 自动打日志的 HOC
场景:每次组件挂载时自动打印日志
// 高阶组件工厂(手机壳生产商)
const withLogger = Component => {
// 返回一个新组件(加了壳的手机)
return function WithLogger(props) {
useEffect(() => {
console.log(`${Component.name} 已挂载`);
}, []);
// 原样传递所有props(手机功能不变)
return <Component {...props} />;
};
};
// 使用(给组件套壳)
const Button = () => <button>按钮</button>;
const ButtonWithLogger = withLogger(Button); // 现在按钮每次挂载会打日志
2. 权限拦截 HOC
场景:根据权限决定是否渲染组件
const withAuth = allowedRoles => Component => {
return function WithAuth(props) {
// 模拟当前用户角色
const currentUserRole = 'admin';
if (!allowedRoles.includes(currentUserRole)) {
return <div>无权限访问!</div>;
}
// 有权限则显示原组件
return <Component {...props} />;
};
};
// 使用(套权限壳)
const AdminPanel = () => <div>管理员面板</div>;
const ProtectedAdminPanel = withAuth(['admin'])(AdminPanel);
// 非admin用户看到的是「无权限」
3. 数据注入 HOC
场景:统一获取数据并注入组件
const withUserData = Component => {
return function WithUserData(props) {
const [userData, setUserData] = useState(null);
useEffect(() => {
fetchUserData().then(data => setUserData(data));
}, []);
// 把数据作为新prop传递(注入)
return <Component {...props} userData={userData} />;
};
};
// 使用(普通组件秒变有数据的组件)
const Profile = ({ userData }) => <div>{userData ? userData.name : '加载中...'}</div>;
const ProfileWithData = withUserData(Profile); // 自动获得userData属性