Skip to content

React 文档

导读与全书目录表:见同目录 01-React 入门:简介·特性与设计范式.md 开头。


高阶组件

  • 高阶组件(Higher-Order Component)是React中用于复用组件逻辑的一种高级技巧。HOC本质上是一个纯函数,它接收一个或多个组件并返回一个新的组件。
  • 类似 vue2 中的混入 mixins,React 16.8引入的更简单的逻辑复用方式,很多HOC场景可以用自定义Hook替代

作用

增强当前组件的功能,逻辑复用

约定

  • 不要以任何方式修改原始组件
  • props 保持一致
  • 不要在render中使用高阶组件,这会导致每次渲染时组件都会卸载和重新挂载
  • ref 指向的是外层的容器组件,如果要使用,需要借助 React.forwardRef

使用场景

  • 处理组件逻辑复用 & 状态管理 & 事件处理等场景
  • loading 条件渲染
  • 数据校验
  • 权限校验
  • 异常处理
  • 通用方法共享

常见模式

  1. 事件处理高阶函数
ts
function withLogging(fn) {
  return function(...args) {
    console.log('函数被调用,参数:', args);
    return fn(...args);
  };
}

// 使用
const handleClickWithLog = withLogging((event) => {
  console.log('按钮被点击');
});

<button onClick={handleClickWithLog}>点击我</button>
  1. 数据转换高阶函数
ts
function withDataTransform(transformFn) {
  return function(data) {
    const transformed = transformFn(data);
    console.log('转换前:', data, '转换后:', transformed);
    return transformed;
  };
}

// 使用
const formatUserData = withDataTransform((user) => ({
  fullName: `${user.firstName} ${user.lastName}`,
  age: new Date().getFullYear() - user.birthYear
}));
  1. 异步操作高阶函数
ts
function withAsyncHandling(fn) {
  return async function(...args) {
    try {
      const result = await fn(...args);
      return result;
    } catch (error) {
      console.error('异步操作失败:', error);
      throw error;
    }
  };
}

// 使用
const fetchDataWithHandling = withAsyncHandling(async (url) => {
  const response = await fetch(url);
  return response.json();
});

实际使用

  1. 组件逻辑复用(高阶组件 HOC)
ts
// 高阶组件示例:添加加载状态
function withLoading(Component) {
    return function EnhancedComponent({ isLoading, ...props }) {
        if (isLoading) {
            return <div>Loading...</div>;
        }
        return <Component {...props} />;
    };
}

// 使用 HOC
function UserList({ users }) {
    return (
        <ul>
            {users.map(user => (
                    <li key={user.id}>{user.name}</li>
                ))}
        </ul>
    );
}

// 增强后的组件
const UserListWithLoading = withLoading(UserList);

// 使用时传入 isLoading 控制状态
<UserListWithLoading isLoading={false} users={[]} />
  1. 表单处理高阶函数
ts
function createInputHandler(setState) {
  return function(event) {
    const { name, value } = event.target;
    setState(prev => ({ ...prev, [name]: value }));
  };
}

// 在组件中使用
function MyForm() {
  const [formData, setFormData] = useState({ username: '', password: '' });
  const handleInputChange = createInputHandler(setFormData);
  
  return (
    <form>
      <input name="username" onChange={handleInputChange} />
      <input name="password" onChange={handleInputChange} />
    </form>
  );
}
  1. 防抖/节流 事件处理高阶函数
ts
function withDebounce(fn, delay) {
  let timer;
  return function(...args) {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), delay);
  };
}

// 使用
function SearchComponent() {
  const [query, setQuery] = useState('');
  
  const handleSearch = useCallback(withDebounce((searchTerm) => {
    console.log('搜索:', searchTerm);
    // 执行搜索API调用
  }, 500), []);
  
  const handleChange = (e) => {
    setQuery(e.target.value);
    handleSearch(e.target.value);
  };
  
  return <input value={query} onChange={handleChange} />;
}

总结

  • 高阶组件是React中强大的代码复用模式,特别适合横切关注点(cross-cutting concerns)的处理。
  • 虽然Hooks的引入减少了对HOC的需求,但在某些场景下HOC仍然是有效的解决方案,特别是在需要增强或修改组件行为时。

注意

  • 避免过度使用:过多嵌套的高阶函数会降低代码可读性(如 "回调地狱" 类似问题)。
  • 与 Hooks 配合:在现代 React 中,Hooks(如 useCallback、useMemo)常与高阶函数结合使用,优化性能。
  • 命名规范:高阶组件通常以 with 为前缀(如 withLoading),清晰表达其增强功能。

react 高阶组件和使用场景

回答

shell
# 概念
“高阶组件 HOC 是一种复用组件逻辑的设计模式,本质是接收一个组件作为参数,返回一个增强后的新组件的纯函数

# 使用场景
常见用于通用数据请求、权限控制、埋点监控、样式增强等跨组件逻辑复用场景
1. 通用数据获取 --- 避免重复写接口请求逻辑
“比如多个组件都需要获取用户信息 / 商品列表,可封装 withFetch 高阶组件,统一处理请求、加载、错误状态,组件只需关注渲染,减少重复代码。”
2. 权限控制 --- 统一校验用户权限
“封装 withAuth 高阶组件,在组件挂载前校验用户是否登录 / 是否有操作权限,无权限则跳转到登录页,所有需要权限的组件只需包裹该 HOC 即可,无需逐个写校验逻辑。”
3. 埋点 / 日志监控 --- 统一处理行为埋点
“比如按钮点击、页面挂载的埋点逻辑,封装 withTrack 高阶组件,统一监听事件并上报,业务组件无需关心埋点细节,只需要传递埋点标识即可。”
4. 样式 / 主题增强 --- 统一注入样式 / 主题属性
“封装 withTheme 高阶组件,向组件注入全局主题变量(如颜色、字体),所有需要适配主题的组件只需包裹该 HOC,即可统一使用主题样式,便于主题切换。

# HOC 的注意事项
“使用 HOC 时要注意避免修改原组件,保持纯函数特性;
同时不要在渲染阶段创建 HOC,否则会导致组件重复挂载;
另外,Hooks 虽然能替代部分 HOC 场景,但 HOC 在全局级别的逻辑复用(如权限控制)上仍有优势,二者可结合使用。”