You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用TypeScript实现为ErrorBoundary提供location的高阶组件(HOC)

解决React Router WithRouter HOC的TypeScript类型问题

我尝试用TypeScript实现一个高阶组件(HOC),将ErrorBoundary组件传入该HOC,让HOC注入用户当前的location属性,以便在ErrorBoundary中使用。现有TypeScript版本的HOC编译报错,JavaScript版本可正常运行,但无法正确转换为TypeScript版本。

现有ErrorBoundary组件代码

import React from "react";

interface ErrorBoundaryProps {
  fallback: React.ReactNode;
  children: React.ReactNode;
  location: {
    pathname: string;
  };
}

class ErrorBoundary extends React.Component<ErrorBoundaryProps> {
  state = { hasError: false };

  static getDerivedStateFromError(error: Error) {
    return { hasError: true };
  }

  componentDidUpdate(previousProps: ErrorBoundaryProps) {
    if (previousProps.location.pathname !== this.props.location.pathname) {
      this.setState({ hasError: false });
    }
  }

  render() {
    if (this.state.hasError) {
      return this.props.fallback;
    }
    return this.props.children;
  }
}

export default ErrorBoundary;

报错的WithRouter HOC代码

import { useLocation } from "react-router-dom";

function WithRouter(OriginalComponent: React.ComponentType) {
  const NewComponent = (props: any) => {
    const location = useLocation();

    return <OriginalComponent {...props} location={location} />;
  };
  return NewComponent;
}

正确的TypeScript实现方案

核心是通过泛型明确HOC的类型约束,避免使用any,同时确保注入的location属性与组件所需类型匹配:

import { useLocation, Location } from "react-router-dom";
import React from "react";

// 泛型HOC:T为组件接收的props(排除location,由HOC注入)
function WithRouter<T extends Omit<ErrorBoundaryProps, 'location'>>(
  OriginalComponent: React.ComponentType<T & { location: Location }>
) {
  const NewComponent: React.FC<T> = (props) => {
    const location = useLocation();
    // 注入location并传递其他props
    return <OriginalComponent {...props} location={location} />;
  };

  // 保留原组件displayName,方便调试
  NewComponent.displayName = `WithRouter(${OriginalComponent.displayName || OriginalComponent.name})`;
  
  return NewComponent;
}

关键类型说明

  • 泛型T接收组件的原始props(排除location,因为HOC会自动注入)
  • 约束OriginalComponent的props为T & { location: Location },确保组件能接收注入的路由location对象
  • NewComponent的props类型为T,外部使用时无需手动传递location
  • 保留原组件的displayName,提升React DevTools的调试体验

使用方式

// 生成带location注入的ErrorBoundary组件
const ErrorBoundaryWithRouter = WithRouter(ErrorBoundary);

// 使用时无需传递location
<ErrorBoundaryWithRouter fallback={<div>出错了</div>}>
  {/* 子组件内容 */}
</ErrorBoundaryWithRouter>

内容的提问来源于stack exchange,提问作者Hussein Khodor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 03:16:34