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

时间:2019-09-07 11:11:23

标签: reactjs typescript react-router-v4

如果我浏览至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)

1 个答案:

答案 0 :(得分:1)

问题是打字稿不知道您的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来使Typescript知道自定义参数密钥存在于路由参数中。

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) => {}