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

如何向withRouter包装的React类组件传递Props?

类组件使用withRouter后Props传递的TypeScript错误

问题重现

有一个需要传递Props的类组件TestClass,定义如下:

type TestProps = {
    location: any
    setMill: (value: any) => void
}

class TestClass extends Component<TestProps> {
    componentDidMount() {
        this.setState({ userRoleRating: 5 });
    }

    render() {
        return <></>
    }
}

export default withRouter(TestClass as any)

在函数组件Layout中调用该类组件并传递setMill属性:

type LayoutProps = {
  children?: React.ReactElement
  setMill: (value: any) => void
}

const Layout: React.FC<LayoutProps> = (props: LayoutProps) => {
  return <>
    <TestClass setMill={props.setMill}/>
    <Container className="root-wrapper">{props.children}</Container>
    <Footer />
  </>
}

export default Layout

出现TypeScript错误:

Type '{ setMill: (value: any) => void; }' is not assignable to type 'IntrinsicAttributes & 
(IntrinsicClassAttributes<Component<Pick<RouteComponentProps<any, 
StaticContext, unknown>, never> | (Pick<RouteComponentProps<any, 
StaticContext, unknown>, never> & { ...; }), any, any>> & 
Readonly<...>)'.

  Property 'setMill' does not exist on type 'IntrinsicAttributes & 
(IntrinsicClassAttributes<Component<Pick<RouteComponentProps<any, 
StaticContext, unknown>, never> | (Pick<RouteComponentProps<any, 
StaticContext, unknown>, never> & { ...; }), any, any>> & 
Readonly<...>)'.ts(2322)

解决方案

问题确实出在withRouter的类型处理上,错误地用as any断言导致TypeScript丢失了组件的Props类型信息。正确的修复步骤如下:

1. 让TestProps继承RouteComponentProps

withRouter会自动注入路由相关Props(比如location),不需要手动在TestProps中声明,直接继承RouteComponentProps即可:

import { Component } from 'react';
import { RouteComponentProps, withRouter } from 'react-router-dom';

// 自定义Props + 路由注入的Props
type TestProps = RouteComponentProps & {
    setMill: (value: any) => void
}

2. 补充类组件的State类型定义

组件中使用了setState,需要明确State的类型:

class TestClass extends Component<TestProps, { userRoleRating: number }> {
    // 初始化state
    state = {
        userRoleRating: 0
    };

    componentDidMount() {
        this.setState({ userRoleRating: 5 });
    }

    render() {
        return <></>
    }
}

3. 正确导出组件,移除as any断言

直接用withRouter包裹组件,不需要类型断言,让TypeScript自动推导类型:

export default withRouter(TestClass);

4. 调用组件时正常传递Props

此时在Layout中传递setMill就不会有类型错误了,原Layout代码无需修改。

完整修改后的代码

// TestClass.tsx
import { Component } from 'react';
import { RouteComponentProps, withRouter } from 'react-router-dom';

type TestProps = RouteComponentProps & {
    setMill: (value: any) => void
}

class TestClass extends Component<TestProps, { userRoleRating: number }> {
    state = {
        userRoleRating: 0
    };

    componentDidMount() {
        this.setState({ userRoleRating: 5 });
    }

    render() {
        return <></>
    }
}

export default withRouter(TestClass);
// Layout.tsx
import React from 'react';
import TestClass from './TestClass';
import { Container } from 'your-ui-library'; // 替换为实际的UI组件
import Footer from './Footer';

type LayoutProps = {
  children?: React.ReactElement
  setMill: (value: any) => void
}

const Layout: React.FC<LayoutProps> = (props: LayoutProps) => {
  return <>
    <TestClass setMill={props.setMill}/>
    <Container className="root-wrapper">{props.children}</Container>
    <Footer />
  </>
}

export default Layout

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 19:01:23