React 常用高阶组件使用

在 React 中,常用的高阶组件(HOC)模式包括增强组件功能、复用逻辑等。它们是接受一个组件并返回一个新组件的函数。高阶组件让我们在不修改原始组件的情况下,扩展组件功能。以下是几个常见的高阶组件的示例:

1. withLoading(加载状态)

withLoading 用于在组件加载数据时显示一个加载指示器。

示例:
javascript 复制代码
import React, { useState, useEffect } from 'react';

const withLoading = (fetchData) => (WrappedComponent) => {
  return (props) => {
    const [state, setState] = useState({ loading: true, data: null, error: null });

    useEffect(() => {
      fetchData()
        .then(data => setState({ loading: false, data }))
        .catch(error => setState({ loading: false, error }));
    }, [fetchData]);

    if (state.loading) return <div>加载中...</div>;
    if (state.error) return <div>加载失败</div>;
    return <WrappedComponent {...props} data={state.data} />;
  };
};

export default withLoading;
使用:
javascript 复制代码
import React from 'react';
import withLoading from './withLoading';

const fetchUserData = ({ data }) => fetch('/api/user').then(res => res.json());
const UserProfile = () => <div>姓名:{data.name}</div>;

export default withLoading(fetchUserData)(UserProfile);

2. withErrorBoundary(错误边界)

withErrorBoundary 用于捕获组件渲染过程中的错误,并显示错误信息。

示例:
javascript 复制代码
import React, { Component } from 'react';

const withErrorBoundary = (WrappedComponent) => {
  return class extends Component {
    state = { hasError: false };
    
    static getDerivedStateFromError() {
      return { hasError: true };
    }

    render() {
      return this.state.hasError ? <div>出了点问题!</div> : <WrappedComponent {...this.props} />;
    }
  };
};

export default withErrorBoundary;
使用:
javascript 复制代码
import React, { useState, useEffect } from 'react';
import withErrorBoundary from './withErrorBoundary';

const fetchUserData = () => fetch('/api/user').then(res => res.json());

const UserProfile = () => {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetchUserData().then(setData).catch(console.error);
  }, []);

  return data ? <h1>{data.name}</h1> : '加载失败';
};

export default withErrorBoundary(UserProfile);

3. withAuth(权限控制)

withAuth 用于检查用户是否登录或有权限访问某个页面。

示例:
javascript 复制代码
import React, { useState, useEffect } from 'react';
import { Redirect } from 'react-router-dom';

const checkAuthStatus = () => fetch('/api/check-auth').then(res => res.json());

const withAuth = (WrappedComponent) => {
  return (props) => {
    const [isAuthenticated, setIsAuthenticated] = useState(null);

    useEffect(() => { checkAuthStatus().then(setIsAuthenticated); }, []);

    if (isAuthenticated === null) return <div>验证中...</div>;
    if (!isAuthenticated) return <Redirect to="/login" />;

    return <WrappedComponent {...props} />;
  };
};

export default withAuth;
使用:
javascript 复制代码
import React from 'react';
import withAuth from './withAuth';

const Dashboard = () => <div>欢迎来到仪表盘</div>;

export default withAuth(Dashboard);

4. withTheme(主题支持)

withTheme 用于为组件提供主题样式或样式变量。

示例:
javascript 复制代码
import React from 'react';

const withTheme = (WrappedComponent) => {
  return (props) => {
    const theme = { backgroundColor: 'lightblue', color: 'darkblue' };

    return <div style={theme}><WrappedComponent {...props} /></div>;
  };
};

export default withTheme;
使用:
javascript 复制代码
import React from 'react';
import withTheme from './withTheme';

const ThemedComponent = () => <div>这是一个主题组件!</div>;

export default withTheme(ThemedComponent);

5. withWindowSize(窗口尺寸)

withWindowSize 用于获取并传递当前窗口的尺寸信息。

示例:
javascript 复制代码
import React, { useState, useEffect } from 'react';

const getWindowSize = () => ({ width: window.innerWidth, height: window.innerHeight });

const withWindowSize = (WrappedComponent) => {
  return (props) => {
    const [size, setSize] = useState(getWindowSize());

    useEffect(() => {
      const handleResize = () => setSize(getWindowSize());
      window.addEventListener('resize', handleResize);
      return () => window.removeEventListener('resize', handleResize);
    }, []);

    return <WrappedComponent {...props} windowSize={size} />;
  };
};

export default withWindowSize;
使用:
javascript 复制代码
import React from 'react';
import withWindowSize from './withWindowSize';

const ResponsiveNavbar = ({ windowSize }) => {
  const isMobile = windowSize.width < 600;
  return (
    <nav style={{ backgroundColor: isMobile ? 'lightblue' : 'darkblue' }}>
      <p>{isMobile ? '移动端导航' : '桌面端导航'}</p>
    </nav>
  );
};

export default withWindowSize(ResponsiveNavbar);

6. withRouter(React Router)

withRouter 是 React Router 提供的 HOC,使组件能够访问路由信息(如路径、历史记录、路由参数等)。

示例:
javascript 复制代码
import React from 'react';
import { withRouter } from 'react-router-dom';

const FormPage = ({ location, history }) => (
  
);

const FormPage = ({ location, history }) => (
  <div>
	<p>当前路径: {location.pathname}</p>
	<button onClick={() => history.push('/new-path')}>跳转</button>
  </div>
);

export default withRouter(FormPage);

7. connect(Redux)

connectreact-redux 提供的,用于将 Redux 的 state 和 actions 绑定到组件的 props。

示例:
javascript 复制代码
import React from 'react';
import { connect } from 'react-redux';
import { increment } from './actions';

const Cart = ({ cart, increment }) => (
  <div>
    {cart.map(item => (
       <li key={item.id}>
          {item.name} - {item.quantity}
          <button onClick={() => increment(item.id)}>增加</button>
       </li>
      ))}
  </div>
);

const mapStateToProps = (state) => ({ cart: state.cart });
const mapDispatchToProps = { increment };

export default connect(mapStateToProps, mapDispatchToProps)(Cart);

总结

高阶组件(HOC)在 React 中提供了一种灵活的方式来复用逻辑并增强组件功能,提升代码复用性和可维护性。以下是常见的 HOC 示例:

  • withLoading:显示加载状态。
  • withErrorBoundary:捕获渲染错误。
  • withAuth:实现权限控制。
  • withTheme:提供主题样式。
  • withWindowSize:获取窗口尺寸。
  • withRouter:访问路由信息。
  • connect:连接 Redux 状态和 actions。
相关推荐
互联网搬砖老肖5 分钟前
Web 架构之负载均衡全解析
前端·架构·负载均衡
sunbyte1 小时前
Tailwind CSS v4 主题化实践入门(自定义 Theme + 主题模式切换)✨
前端·javascript·css·tailwindcss
风之舞_yjf2 小时前
Vue基础(8)_监视属性、深度监视、监视的简写形式
javascript·vue.js·ecmascript
湛海不过深蓝2 小时前
【css】css统一设置变量
前端·css
DONSEE广东东信智能读卡器2 小时前
蓝牙身份证阅读器使用Uniapp调用二次开发demo
javascript·uni-app·蓝牙·身份证阅读器
Codingwiz_Joy2 小时前
Day28 -js开发01 -JS三个实例:文件上传 & 登录验证 & 购物商城 & ---逻辑漏洞复现 及 判断js的payload思路
开发语言·javascript·安全·安全性测试
程序员的世界你不懂2 小时前
tomcat6性能优化
前端·性能优化·firefox
爱吃巧克力的程序媛2 小时前
QML ProgressBar控件详解
前端
进取星辰2 小时前
21、魔法传送阵——React 19 文件上传优化
前端·react.js·前端框架
wqqqianqian2 小时前
国产linux系统(银河麒麟,统信uos)使用 PageOffice 在线打开Word文件,并用前端对话框实现填空填表
linux·前端·word·pageoffice