【问题标题】:How to set correctly React routes?如何正确设置 React 路由?
【发布时间】:2021-08-02 09:41:05
【问题描述】:

我正在使用 React 构建一个应用程序,并且我正在使用 React 路由。

我有 3 条主要路线:

  • 如果用户已登录,则显示仪表板
  • 如果用户未登录,则显示登录页面
  • 如果用户在登录页面点击 ForgotPassword,更改 url 并显示 ForgotPassword 页面

index.js

ReactDOM.render(
    <Provider store={store}>
        <BrowserRouter>
            <Suspense fallback={<div>Loading...</div>}>
                <div>
                    <Switch>
                        <Route path="/" component={App} />
                        <Route path="/login" component={Login} />
                        <Route path="/forgotPassword" component={ForgotPassword} />
                    </Switch>
                </div>
            </Suspense>
        </BrowserRouter>
    </Provider>,
  document.getElementById('root')
);

App.js

{this.props.location.pathname === "/" && <Dashboard />}
<Route exact path="/users" component={Users} />
<Route path="/users/:id" component={UserPage} />
{!authenticated && <Redirect to="/login" />}

当我尝试打开"/" 时,它会重定向到"/login",但它不会呈现Login 组件。
当我用{!authenticated &amp;&amp; &lt;Login&gt;} 替换{!authenticated &amp;&amp; &lt;Redirect to="/login" /&gt;} 时,它会正确呈现组件,但它不会更改 url,也不会显示 ForgotPassword 页面。

如何正确设置?

【问题讨论】:

  • 您是否在所有路由中尝试&lt;Route exact path="/" component={App} /&gt;exact

标签: reactjs react-router-dom


【解决方案1】:

您需要重新订购交换机:

<Switch>
    <Route path="/login" component={Login} />
    <Route path="/forgotPassword" component={ForgotPassword} />
    <Route path="/" component={App} />
</Switch>

然后,也许把 App 写成类似

{!authenticated ? <Redirect to="/login" /> : (
  <Switch>
    <Route path="/users/:id" component={UserPage} />
    <Route exact path="/users" component={Users} />
    <Route path="/" component={Dashboard />
  </Switch>
)}

(尽管将所有路由保留在*路由器/交换机中可能更简单)

【讨论】:

    【解决方案2】:

    问题是Route 组件的顺序和Switch 组件的使用。

    当你重定向到/login时,Switch会渲染第一个匹配的路由;对于/login 路由,/ 路由也匹配。

    这就是Login 组件没有被渲染的原因。 App 组件为 //login 路由呈现。

    解决方案

    这个问题的几个解决方案描述如下:

    exact道具

    解决问题的一种方法是使用exact 属性。这将确保 / 路由不匹配 /login 但它会导致另一个问题:App 组件内的嵌套路由不会被渲染。这是因为要渲染嵌套路由,还需要渲染父路由。

    重新排序Route 组件

    另一种解决方案是将路线的顺序更改为:

    <Switch>
       <Route path="/login" component={Login} />
       <Route path="/forgotPassword" component={ForgotPassword} />
       <Route path="/" component={App} />
    </Switch>
                            
    

    【讨论】:

      【解决方案3】:

      您必须使用 render prop 而不是组件,而 render prop 使您能够进行一些检查并返回适当的组件

      <Route render={(props) => !isAuth ? <Redirect to='/signin' /> : <Component {...props} /> } />
      

      【讨论】: