React Typescript:配置路由器以允许基于 URL 的用户名而不与其他路由冲突

React Typescript: Configure router to allow username based URL's without conflicting with other routes

我想在 URL 上查看我的用户个人资料,例如 www.domain.com/<userName> 我想加载 ShowProfile 现在我可以确保 terms 不是用户名,而是如果我浏览到 www.domain.com/terms 我不想加载 ShowProfile 但我想加载 Terms.

import React, { useReducer } from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import { Layout } from './components/layout';
import { Dispatch, Global, InitialState, Reducer } from './globalState';
import { ConfirmEmail } from './routes/confirmEmail';
import { Home } from './routes/home';
import { NotFound } from './routes/notFound';
import { Profile } from './routes/profile';
import { Terms } from './routes/terms';
import { ShowProfile } from './routes/showProfile';
import { ResetPassword } from './routes/resetPassword';

const Router: React.FC = () => {
  const [global, dispatch] = useReducer(Reducer, InitialState);
  return (
    <Dispatch.Provider value={{ dispatch }}>
      <Global.Provider value={{ global }}>
        <BrowserRouter>
          <Route
            render={({ location }) => (
              <Layout location={location}>
                <Switch location={location}>
                  <Route exact path='/' component={Home} />
                  <Route exact path='/:userName' component={ShowProfile} /> //<<== I want to view I users profile on a URL like this but the other routes break
                  <Route exact path='/terms' component={Terms} />                  
                  <Route exact path='/my/profile' component={Profile} />
                  <Route exact path='/confirm-email/:confirmationCode' component={ConfirmEmail} />
                  <Route exact path='/reset-password/:resetPassword' component={ResetPassword} />
                  <Route component={NotFound} />
                </Switch>
              </Layout>
            )}
          />
        </BrowserRouter>
      </Global.Provider>
    </Dispatch.Provider>
  );
};

export { Router };

也许你应该更改路径?

'/:userName' => '/users/:userName'

你不会发现用户名有任何问题,例如:terms、confirm-email、reset-password、其他路由

但如果你想要你的方式,你可以尝试使用状态,以下是我的想法:

<Route exact path='/' component={Home} />

{global.isUserRoute ?
    <Route exact path='/:userName' component={ShowProfile} /> //<<== I want to view I users profile on a URL like this but the other routes break
    :
    <>
        <Route exact path='/terms' component={Terms} />
        <Route exact path='/about' component={About} />
        // single routes...
    </>
}

// ...other specific routes with more then one slash                  
<Route exact path='/my/profile' component={Profile} />
<Route exact path='/confirm-email/:confirmationCode' component={ConfirmEmail} />
<Route exact path='/reset-password/:resetPassword' component={ResetPassword} />
<Route component={NotFound} />

例如,您可以在获取用户配置文件时更改 isUserRoute = true,在 componentWillUnmount

中更改 isUserRoute = false

请尝试

<Switch location={location}>
  <Route exact path='/' component={Home} />
  <Route exact path='/terms' component={Terms} />                  
  <Route exact path='/my/profile' component={Profile} />
  <Route exact path='/confirm-email/:confirmationCode' component={ConfirmEmail} />
  <Route exact path='/reset-password/:resetPassword' component={ResetPassword} />
  <Route path='/:userName' component={ShowProfile} />
  <Route component={NotFound} />
<Switch>

并且不要忘记禁止注册与路由匹配的用户名