【问题标题】:What TypeScript type should I use to reference the match object in my props?我应该使用什么 TypeScript 类型来引用我的道具中的匹配对象?
【发布时间】:2018-06-16 17:06:14
【问题描述】:

在我的 React 容器/组件中,我可以使用哪种类型来引用 React Router DOM 包含的 match 部分?

interface Props {
  match: any // <= What could I use here instead of any?
}

export class ProductContainer extends React.Component<Props> {
  // ...
}

【问题讨论】:

    标签: reactjs typescript react-router


    【解决方案1】:

    这是我测试的完整示例。

    DemoComponent.tsx

    // Created by BaiJiFeiLong@gmail.com at 2021/9/25 20:15
    
    import React from "react";
    import {RouteComponentProps} from "react-router"
    
    export default class DemoComponent extends React.Component<{
        prop1: string,
        prop2: string,
        prop3: string
    } & RouteComponentProps<{
        param1: string,
        param2: string,
        param3: string
    }>, {
        state1: string,
        state2: string,
        state3: string
    }> {
    
        static defaultProps = {
            prop1: "PROP1",
            prop2: "PROP2",
            prop3: "PROP3"
        }
    
        constructor(props: any) {
            super(props);
            this.state = {
                state1: "STATE1",
                state2: "STATE2",
                state3: "STATE3"
            }
        }
    
    
        render() {
            return <ul>
                <li>prop1 = {this.props.prop1}</li>
                <li>prop2 = {this.props.prop2}</li>
                <li>prop3 = {this.props.prop3}</li>
                <li>state1 = {this.state.state1}</li>
                <li>state2 = {this.state.state2}</li>
                <li>state3 = {this.state.state3}</li>
                <li>param1 = {this.props.match.params.param1}</li>
                <li>param2 = {this.props.match.params.param2}</li>
                <li>param3 = {this.props.match.params.param3}</li>
            </ul>
        }
    }
    

    路线

    <Route exact path="/demo/:param1/:param2/:param3" component={DemoComponent}/>
    

    来电

    /demo/foo/bar/baz
    

    结果

    prop1 = PROP1
    prop2 = PROP2
    prop3 = PROP3
    state1 = STATE1
    state2 = STATE2
    state3 = STATE3
    param1 = foo
    param2 = bar
    param3 = baz
    

    【讨论】:

      【解决方案2】:

      简单的解决方案

      import { RouteComponentProps } from "react-router-dom";
      
      const Container = ({ match }: RouteComponentProps<{ showId?: string}>) => {
       const { showId } = match.params?.showId;//in case you need to take params
      }
      

      【讨论】:

        【解决方案3】:

        问题是即使在为match&lt;Params&gt; 创建了一个接口之后,类型警告仍然存在。这是对我有用的代码:

        interface MatchParams {
            firstParam: string;
            optionalParam?: string;
        }
        
        export const CreditPortfolioDetail: FC<RouteComponentProps<MatchParams>> = (props) => {
            const { firstParam, optionalParam} = props.match.params; 
            // ...
        }
        

        【讨论】:

        • 什么是 FC ? FC>
        • 它是 React.FC,它是 React.FunctionComponent 的类型别名。您的函数实际上是一个 FunctionComponent,通过明确说明,您还可以将 children 属性自动添加到您的道具中(类似于 RouteComponentProps 如何自动添加位置、匹配等)
        【解决方案4】:

        您不需要显式添加它。你可以使用来自@types/react-routerRouteComponentProps&lt;P&gt; 作为道具的基本接口。 P 是匹配参数的类型。

        import { RouteComponentProps } from 'react-router';
        
        // example route
        <Route path="/products/:name" component={ProductContainer} />
        
        interface MatchParams {
            name: string;
        }
        
        interface Props extends RouteComponentProps<MatchParams> {
        }
        
        // from typings
        import * as H from "history";
        
        export interface RouteComponentProps<P> {
          match: match<P>;
          location: H.Location;
          history: H.History;
          staticContext?: any;
        }
        
        export interface match<P> {
          params: P;
          isExact: boolean;
          path: string;
          url: string;
        }
        

        【讨论】:

        • 这个问题是 Typescript 然后期望该组件的每次使用都实际传递到位置历史道具等中。RouteComponentProps 应该将这些道具作为可选的。必须用 Partial 包装。
        • @Glstunna 感谢您让我意识到,如果使用部分功能会怎样?以及 OP:请包括您的导入。
        • TypeScript 一直要求我将整个道具集传递给组件(`,我也有代码如上所示。
        • @LeonardoViada 尝试使用&lt;Route component={MyComp} /&gt;传递组件
        【解决方案5】:

        要添加到上面@Nazar554 的答案,RouteComponentProps 类型应从react-router-dom 导入,并按如下方式实现。

        import {BrowserRouter as Router, Route, RouteComponentProps } from 'react-router-dom';
        
        interface MatchParams {
            name: string;
        }
        
        interface MatchProps extends RouteComponentProps<MatchParams> {
        }
        

        此外,为了允许可重复使用的组件,render() 函数允许您仅传递组件需要的内容,而不是整个 RouteComponentProps

        <Route path="/products/:name" render={( {match}: MatchProps) => (
            <ProductContainer name={match.params.name} /> )} />
        
        // Now Product container takes a `string`, rather than a `MatchProps`
        // This allows us to use ProductContainer elsewhere, in a non-router setting!
        const ProductContainer = ( {name}: string ) => {
             return (<h1>Product Container Named: {name}</h1>)
        }
        

        【讨论】:

        • 太棒了!不错的补充
        猜你喜欢
        • 2019-04-05
        • 2017-04-14
        • 1970-01-01
        • 1970-01-01
        • 2019-06-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-28
        相关资源
        最近更新 更多