高阶组件(Higher-Order Component,简称HOC)是JavaScript中用于复用组件逻辑的一种高级技巧,本质上是一个函数,接收一个组件作为参数,返回一个新的增强后的组件。它不属于React的API,而是基于JavaScript函数式编程特性衍生出来的设计模式,在React项目开发中应用十分广泛。

高阶组件的核心实现思路
高阶组件的实现基于两个核心特性:函数可以作为参数传递,函数可以作为返回值。我们不需要依赖任何框架,仅用原生JavaScript就可以实现基础的高阶组件,核心逻辑是对传入的组件进行包装,添加额外的属性、方法或者生命周期逻辑。
基础原生JS实现示例
下面是一个最简单的原生JS高阶组件实现,它接收一个组件,返回一个新组件,新组件会在原始组件的基础上新增一个固定的属性:
// 定义一个基础组件
function BaseComponent(props) {
return {
render: function() {
return `渲染组件,接收的属性:name=${props.name}`;
}
};
}
// 定义高阶组件,接收组件作为参数
function withExtraProp(WrappedComponent, extraProp) {
// 返回一个新的组件函数
return function(props) {
// 合并原始属性和新增的额外属性
const newProps = Object.assign({}, props, extraProp);
// 创建原始组件的实例
const instance = WrappedComponent(newProps);
// 返回增强后的实例
return {
render: instance.render
};
};
}
// 使用高阶组件增强BaseComponent
const EnhancedComponent = withExtraProp(BaseComponent, { age: 18 });
// 创建增强组件的实例并调用渲染方法
const enhancedInstance = EnhancedComponent({ name: '测试组件' });
console.log(enhancedInstance.render());
React环境下的高阶组件实现
在React项目中,高阶组件的使用更加常见,通常用来增强类组件或者函数组件的能力,下面是一个React函数组件的高阶组件示例:
import React from 'react';
// 高阶组件:给传入的组件添加加载状态
function withLoading(WrappedComponent) {
return function WithLoadingComponent(props) {
// 如果传入了isLoading属性且为true,显示加载状态
if (props.isLoading) {
return <div>加载中...</div>;
}
// 否则渲染原始组件,透传所有属性
return <WrappedComponent {...props} />;
};
}
// 定义一个普通的列表组件
function List(props) {
return (
<ul>
{props.data.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
);
}
// 用高阶组件增强List组件
const ListWithLoading = withLoading(List);
// 使用增强后的组件
function App() {
const [loading, setLoading] = React.useState(true);
const data = ['选项1', '选项2', '选项3'];
React.useEffect(() => {
// 模拟2秒后加载完成
setTimeout(() => setLoading(false), 2000);
}, []);
return <ListWithLoading isLoading={loading} data={data} />;
}
高阶组件的常见应用场景
高阶组件的核心价值是逻辑复用,以下是几个最典型的应用场景:
1. 日志记录与性能监控
我们可以通过高阶组件包装组件,自动记录组件的挂载、更新、卸载时间,或者上报组件的使用数据,不需要在每个组件内部重复编写这些逻辑:
function withLog(WrappedComponent) {
const componentName = WrappedComponent.name || 'UnknownComponent';
return class extends React.Component {
componentDidMount() {
console.log(`${componentName} 组件挂载时间:${new Date().toLocaleString()}`);
}
componentWillUnmount() {
console.log(`${componentName} 组件卸载时间:${new Date().toLocaleString()}`);
}
render() {
return <WrappedComponent {...this.props} />;
}
};
}
2. 权限校验
对于需要登录或者特定角色才能访问的组件,可以用高阶组件统一处理权限逻辑,校验不通过时跳转到登录页或者提示无权限:
function withAuth(WrappedComponent, requiredRole) {
return function AuthComponent(props) {
const currentRole = localStorage.getItem('userRole');
// 如果角色不满足要求,显示无权限提示
if (currentRole !== requiredRole) {
return <div>无权限访问该页面</div>
}
return <WrappedComponent {...props} />;
};
}
// 只有管理员角色才能访问的页面组件
function AdminPage() {
return <div>管理员专属页面</div>
}
const AuthAdminPage = withAuth(AdminPage, 'admin');
3. 数据请求与状态管理
高阶组件可以封装数据请求的逻辑,自动处理请求中的加载、错误、数据状态,让业务组件只需要关注数据的渲染:
function withFetchData(WrappedComponent, fetchApi) {
return class extends React.Component {
state = {
data: null,
loading: true,
error: null
};
componentDidMount() {
fetchApi()
.then(data => this.setState({ data, loading: false }))
.catch(error => this.setState({ error, loading: false }));
}
render() {
const { data, loading, error } = this.state;
if (loading) return <div>加载中...</div>;
if (error) return <div>请求失败:{error.message}</div>;
return <WrappedComponent data={data} {...this.props} />;
}
};
}
使用高阶组件的注意事项
- 不要在高阶组件内部修改原始组件,应该返回一个新的组件,遵循函数式编程的无副作用原则。
- 透传所有不相关的props,避免丢失原始组件需要的属性。
- 高阶组件的显示名称可以自定义,方便React DevTools调试,比如给返回的类组件设置
displayName属性。 - 不要在render方法内部创建高阶组件,否则每次渲染都会生成新的组件,导致不必要的重新挂载。
高阶组件HOCJavaScriptReact修改时间:2026-06-11 18:12:31