【问题标题】:React router switch doesn't match on first loadReact 路由器开关在第一次加载时不匹配
【发布时间】:2021-12-30 18:38:16
【问题描述】:

我有以下swtich 使用react-router。当我打开 new 选项卡并转到任何路径时,它总是重定向到 /login。如果我删除底部开关(没有路径 - 默认),它会按预期工作。如果我导航到任何路径已经加载 react 应用程序(即来自/login),它会按预期工作。

当包含 nomatch 时,为什么开关明显没有检测到正确的路径仅在第一次加载时

编辑:为清楚起见,这是在localhostreact-router-dom v5.2 上使用hashRouter

<Switch>
        <div className="loginForm align-middle">
            <img src="./img/logo.svg" alt="Restocker logo" className="w-100 p-3 mb-4"/>
            <Route path="/verify">
                <Verify/>
            </Route>
            <Route path="/reVerify">
                <ReVerify/>
            </Route>
            <Route path="/register">
                <Register/>
            </Route>
            <Route path="/forgotPassword">
                <ForgotPassword/>
            </Route>
            <Route path="/resetPassword">
                <Verify type={"password"}/>
            </Route>
            <Route path="/login">
                <Login/>
            </Route>
            <Route> //same result using path="*"
                //no match - default to login
                <Redirect to="/login"/>
            </Route>
        </div>
    </Switch>

类似的主题似乎不适用于这种情况 - 要么指根本不匹配(我的一旦加载就会匹配),要么来自更旧的 (2015) 版本。

【问题讨论】:

  • 如果您希望Switch 组件正常工作,应该直接包装Route 组件。使用Switch outside 包装器div 时,所有内部路由都被包含性地匹配和渲染,因此渲染Redirect 的通用路由总是被匹配和渲染。路由不工作时的 URL/路径是什么?
  • @DrewReese 抱歉,我错过了您的评论,但通过反复试验得出了相同的结论 - 您完全正确的是导致行为的间接包装 - 谢谢!

标签: javascript reactjs react-router react-router-dom


【解决方案1】:

请务必注意,当前版本的 react-router-dom v6 不支持 &lt;switch&gt; 组件,而是使用 &lt;BrowserRouter&gt;,我喜欢将其导入为 &lt;Router&gt;

import {
  BrowserRouter as Router,
  Route,
  Routes,
} from "react-router-dom";

另外,v6 使用&lt;element&gt; 组件来调用您希望在特定路由上运行的组件。

<Router>
    <Navbar/>
    <Routes>
      <Route path="/" element={<Home />} />
       <Route path="about" element={<AboutPage />} />
       <Route path="contact" element={<ContactPage />} />
      </Routes>
    </Router>

这意味着您还必须导入这些组件。

import Navbar from "./components/NavBar";
import Home from "./pages";
import AboutPage from "./pages/aboutPage";
import ContactPage from "./pages/contactPage";

我已经包含了一个导航栏组件并将其放置在&lt;Router&gt; 之外但在&lt;Routes&gt; 之外,以便导航出现在所有路线上。但这更多是一种设计选择。

您可能还会遇到一个问题,即您的路线将打开并在您单击路线时所在的屏幕上的同一区域进行分页。如果您需要帮助,请告诉我。如果您的应用不超过整页长度,则可能不需要它

【讨论】:

  • react-router-dom v6 和 OP 的问题有什么关系?他们使用的是Switch 组件,因此他们显然使用的是旧版本。
  • 感谢您的回答,但我使用的是 v5(甚至不知道 v6 已经发布!),我只选择了开关代码,但它被包裹在 &lt;Router/&gt; 更高的树 - 就像我说的那样,except 在第一次加载时工作正常 only 当包含 noMatch 路由时
  • 在我看来,更新到 V6 可能会更好。有许多新的有用功能,例如受限路线等等
  • 如果他们在使用 RRDv6 并且仍在尝试使用 Switch,则会出现错误/警告。由于没有提及这些并且应用程序正在渲染,因此可以安全地假设未使用 v6。
  • @MichaelKhaikin 我理解你的意思,但没有抛出任何错误 - 设置正常工作,除了在这个非常特殊的情况下,我试图理解为什么。升级到 v6 并不能真正回答我的问题,如果不再支持交换机,这表明需要进行大量迁移工作
【解决方案2】:

我认为这很愚蠢 - 包含 div 应该在 switch 之外。它现在按预期工作(我也改为使用 component 道具而不是孩子,但一旦 div 被移动,两者似乎都可以工作)。

工作代码:

    <div className="loginForm align-middle">
        <img src="./img/logo.svg" alt="Restocker logo" className="w-100 p-3 mb-4"/>
        <Switch>
            <Route path="/verify" component={Verify}/>
            <Route path="/reVerify" component={ReVerify}/>
            <Route path="/register" component={Register}/>
            <Route path="/forgotPassword" component={ForgotPassword}/>
            <Route path="/resetPassword" render={() => Verify("password")}/>
            <Route path="/login" component={Login}/>
            <Redirect to="/login"/>
        </Switch>
    </div>

注意现在Switch 的所有直系子代现在都只有Route

编辑根据Drew Reese的建议进行了调整

【讨论】:

  • "/resetPassword" 路由应该使用 render 属性,如果你想通过 type 属性,即&lt;Route path="/resetPassword" render={props =&gt; &lt;Verify type="password" {...props} /&gt;} /&gt;。另外,Redirect 不需要包裹在通用的Route 中,可以直接在Switch 中渲染Redirect
  • @DrewReese 你是对的,谢谢你的建议!
猜你喜欢
  • 1970-01-01
  • 2021-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-21
  • 2019-01-16
  • 1970-01-01
  • 2018-02-21
相关资源
最近更新 更多