React Typescript:使用 BrowserRouter 的通配符路由

React Typescript: Wildcard Routes with BrowserRouter

如果我浏览到 http://localhost:3000/confirm_email/,路由会按预期加载,但如果我浏览到 http://localhost:3000/confirm_email/h8s03kdbx73itls874yfhd,其中 h8s03kdbx73itls874yfhd 对每个用户来说都是不同的,我仍然想加载 / confirm_email 路线,我希望能够获得 h8s03kdbx73itls874yfhd 作为变量。

import React, {useState} from 'react';
import {BrowserRouter, Switch, Route} from 'react-router-dom';
import {CSSTransition, TransitionGroup} from 'react-transition-group'
import {Layout} from "./components/layout";
import Home from './routes/home';
import Direction from './routes/direction';
import NotFound from './routes/not-found';


const Router: React.FC = () => {
  return (    
    <Context.Provider value={{ global, setGlobal }}>
        <BrowserRouter>
        <Layout>
          <Route render={({location}) => (
            <TransitionGroup>
              <CSSTransition timeout={450} classNames='fade' key={location.key}>
                <Switch location={location}>
                  <Route exact path = '/' component = {Home} />
                  <Route exact path = '/direction' component = {Direction} />
                  <Route exact path = '/confirm_email/:confirmationCode' component = {Confirm} />
                  <Route component = {NotFound}/>
                </Switch>
              </CSSTransition>
            </TransitionGroup>
          )} />
          </Layout>
        </BrowserRouter>
    </Context.Provider>
  );
}

export default Router;

然后confirm_email尝试登出确认码

import React from "react";
import {RouteComponentProps} from 'react-router-dom';

interface MyProps {
  confirmationCode: string,
}

const Confirm: React.FC<MyProps & RouteComponentProps> = (props) => {
  console.log(props.match.params.confirmationCode)
  return (
    <div className='page'>Confirm</div>
  );

} 

export default Confirm;

错误是 the error I get is Property 'confirmationCode' does not exist on type '{}'.ts(2339)

问题是 Typescript 不知道您的 confirmationCode 存在于 RouteComponentProps 上。相反,如果您查看 RouteComponentProps 的输入,您会看到 match: match<Params> 被默认定义为空 {}

export interface RouteComponentProps<Params extends { [K in keyof Params]?: string } = {}, C extends StaticContext = StaticContext, S = H.LocationState> {
  history: H.History;
  location: H.Location<S>;
  match: match<Params>;
  staticContext?: C;
}

要解决此问题,您必须通过将所需对象显式传递给 RouteComponentProps.

让打字稿知道您的自定义参数键存在于路由参数中
import React from "react";
import {RouteComponentProps} from 'react-router-dom';

interface MyProps {
  confirmationCode: string,
}

const Confirm: React.FC<RouteComponentProps<MyProps>> = (props) => {
  console.log(props.match.params.confirmationCode)
  return (
    <div className='page'>Confirm</div>
  );
} 

export default Confirm;

或者,您可以更具声明性并使用 type 以获得更简洁的语法,例如:

interface MyProps {
  confirmationCode: string,
}

type MyRouteParams = RouteComponentProps<MyProps>;

const Confirm: React.FC<MyRouteParams> = (props) => {}