React 高阶组件
在 React 中,高阶组件(Higher-Order Component,简称 HOC)是一种高级技巧,用于复用组件逻辑。它是一个函数,接收一个组件作为参数,并返回一个新的增强组件。
概念
- 本质是一个函数,不是组件
- 接收一个组件作为参数
- 返回一个新的组件
- 新组件拥有原组件的功能,同时增加了新功能
用途
- 代码复用
- 逻辑抽象
- Props 增强
- 生命周期劫持
示例
下面是一个简单的高阶组件示例,用于给组件添加加载状态:
// 高阶组件:添加加载状态
function withLoading(Component) {// 返回一个新组件return function (props) {// 如果正在加载,显示加载提示if (props.isLoading) {return <div>Loading...</div>;}// 否则传递所有 props 给原组件return <Component {...props} />;};
}// 普通组件
function UserList({ users }) {return (<ul>{users.map(user => (<li key={user.id}>{user.name}</li>))}</ul>);
}// 使用高阶组件增强 UserList
const UserListWithLoading = withLoading(UserList);// 使用增强后的组件
function App() {const [users, setUsers] = useState([]);const [isLoading, setIsLoading] = useState(true);useEffect(() => {// 模拟数据加载setTimeout(() => {setUsers([{ id: 1, name: 'John' },{ id: 2, name: 'Jane' }]);setIsLoading(false);}, 2000);}, []);return <UserListWithLoading users={users} isLoading={isLoading} />;
}
注意事项
- 不要在渲染方法中使用高阶组件,这会导致每次渲染都创建新组件,引发性能问题和状态丢失
- 传递不相关的 props,确保高阶组件只处理它关心的 props,其余的应传递给被包装组件
- 包装显示名称,为了调试方便,可以设置新组件的 displayName
- 不要在高阶组件内部修改原组件,应该使用组合的方式
带参数的高阶组件
高阶组件还可以接收额外的参数,增加灵活性:
// 带参数的高阶组件
function withData(url) {return function (Component) {return function (props) {const [data, setData] = useState(null);const [isLoading, setIsLoading] = useState(true);useEffect(() => {fetch(url).then(response => response.json()).then(data => {setData(data);setIsLoading(false);});}, [url]);if (isLoading) return <div>Loading...</div>;return <Component data={data} {...props} />;};};
}// 使用带参数的高阶组件
const UserListWithData = withData('/api/users')(UserList);