【React】常见的 HOC 使用案例

高阶组件(Higher-Order Component,HOC)是一种用于在 React 中复用组件逻辑的技术。以下是几个常见的 HOC 使用案例,以及详细的代码示例。

1. 日志记录 HOC

这个高阶组件将在每次组件更新时记录日志。

LoggingHOC.js
js 复制代码
import React from 'react';

const withLogging = (WrappedComponent) => {
  return class extends React.Component {
    componentDidMount() {
      console.log(`${WrappedComponent.name} mounted`);
    }

    componentDidUpdate() {
      console.log(`${WrappedComponent.name} updated`);
    }

    componentWillUnmount() {
      console.log(`${WrappedComponent.name} will unmount`);
    }

    render() {
      return <WrappedComponent {...this.props} />;
    }
  };
};

export default withLogging;
使用日志记录 HOC
js 复制代码
// src/App.js
import React from 'react';
import withLogging from './LoggingHOC';

const MyComponent = () => {
  return <div>My Component</div>;
};

const LoggedMyComponent = withLogging(MyComponent);

const App = () => {
  return (
    <div>
      <LoggedMyComponent />
    </div>
  );
};

export default App;

2. 数据获取 HOC

这个高阶组件在组件挂载时从一个 API 获取数据,并将数据传递给被包装的组件。

FetchDataHOC.js
js 复制代码
import React from 'react';

const withFetchData = (url) => (WrappedComponent) => {
  return class extends React.Component {
    state = {
      data: null,
      loading: true,
      error: null,
    };

    async componentDidMount() {
      try {
        const response = await fetch(url);
        const data = await response.json();
        this.setState({ data, loading: false });
      } catch (error) {
        this.setState({ error, loading: false });
      }
    }

    render() {
      const { data, loading, error } = this.state;
      return <WrappedComponent data={data} loading={loading} error={error} {...this.props} />;
    }
  };
};

export default withFetchData;
使用数据获取 HOC
js 复制代码
// src/App.js
import React from 'react';
import withFetchData from './FetchDataHOC';

const DataComponent = ({ data, loading, error }) => {
  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;
  return <div>Data: {JSON.stringify(data)}</div>;
};

const FetchDataComponent = withFetchData('https://api.example.com/data')(DataComponent);

const App = () => {
  return (
    <div>
      <FetchDataComponent />
    </div>
  );
};

export default App;

3. 权限控制 HOC

这个高阶组件根据用户权限来控制组件的渲染。

withAuthorization.js
js 复制代码
import React from 'react';

const withAuthorization = (requiredRole) => (WrappedComponent) => {
  return class extends React.Component {
    render() {
      const { user } = this.props;
      if (user.role !== requiredRole) {
        return <div>You do not have permission to view this page</div>;
      }
      return <WrappedComponent {...this.props} />;
    }
  };
};

export default withAuthorization;
使用权限控制 HOC
js 复制代码
// src/App.js
import React from 'react';
import withAuthorization from './withAuthorization';

const AdminPage = () => {
  return <div>Admin Page</div>;
};

const AuthorizedAdminPage = withAuthorization('admin')(AdminPage);

const App = () => {
  const user = { role: 'user' }; // change to 'admin' to see the page
  return (
    <div>
      <AuthorizedAdminPage user={user} />
    </div>
  );
};

export default App;

4. 动态样式 HOC

这个高阶组件根据 props 动态添加样式。

withDynamicStyles.js
js 复制代码
import React from 'react';

const withDynamicStyles = (WrappedComponent) => {
  return class extends React.Component {
    render() {
      const style = {
        color: this.props.color || 'black',
        fontSize: this.props.fontSize || '16px',
      };
      return <WrappedComponent {...this.props} style={style} />;
    }
  };
};

export default withDynamicStyles;
使用动态样式 HOC
js 复制代码
// src/App.js
import React from 'react';
import withDynamicStyles from './withDynamicStyles';

const StyledComponent = ({ style }) => {
  return <div style={style}>Styled Component</div>;
};

const DynamicStyledComponent = withDynamicStyles(StyledComponent);

const App = () => {
  return (
    <div>
      <DynamicStyledComponent color="red" fontSize="20px" />
    </div>
  );
};

export default App;

总结

高阶组件是一种强大的模式,可以在 React 中实现代码复用和逻辑抽象。通过高阶组件,你可以:

  • 提取和重用跨组件的逻辑
  • 控制组件的渲染
  • 操作传递给组件的 props
  • 管理和注入状态
相关推荐
漂流瓶jz5 小时前
Webpack如何实现万物皆可import?loader的使用/配置/手写实践
前端·javascript·webpack
ZC跨境爬虫5 小时前
跟着 MDN 学CSS day_41:显式轨道、隐式网格与区域命名放置
前端·javascript·css·ui·交互
weelinking6 小时前
【产品】12_接入数据库——让数据永久保存
jvm·数据库·python·react.js·数据挖掘·前端框架·产品经理
修己xj6 小时前
告别手动存图!这款叫 Fatkun 的浏览器插件,简直是素材收集神器
前端
袋鼠云数栈7 小时前
从前端到基础设施,ACOS 如何打通企业全链路可观测
运维·前端·人工智能·数据治理·数据智能
AskHarries7 小时前
系统提示词、开发者指令和用户输入的优先级
java·前端·数据库
Moment7 小时前
长上下文会最终杀死 Rag 吗?
前端·javascript·后端
qcx238 小时前
【系统学AI】25 论文导读 ①:两篇改变 AI 的开山之作——Attention Is All You Need & ReAct
前端·人工智能·react.js·transformer
kyriewen9 小时前
大文件上传最全指南:分片、断点续传、秒传,一篇就够了
前端·javascript·面试
我叫黑大帅9 小时前
解决聊天页内部滚轮改为页面滚动问题
javascript·后端·面试