Kir*_*ran 10 reactjs react-router
我试图了解在使用 React Router 时看到的特定警告背后的细微差别。我试图根据用户是否登录来设置条件路由。我的代码如下:
\n// AppRoutes.js\nexport\xc2\xa0const\xc2\xa0AppRoutes\xc2\xa0=\xc2\xa0({\xc2\xa0machine\xc2\xa0})\xc2\xa0=>\xc2\xa0{\n\xc2\xa0\xc2\xa0const\xc2\xa0[state]\xc2\xa0=\xc2\xa0useMachine(machine);\n \n let\xc2\xa0routes;\n \n\xc2\xa0\xc2\xa0if\xc2\xa0(state.matches(\'authenticated\'))\xc2\xa0{\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0routes\xc2\xa0=\xc2\xa0(\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<React.Fragment>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<Route\xc2\xa0exact\xc2\xa0path="/"><HomePage\xc2\xa0/></Route>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<Route\xc2\xa0path="/contacts"><ContactsList\xc2\xa0/></Route>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0</React.Fragment>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0);\n\xc2\xa0\xc2\xa0}\xc2\xa0else\xc2\xa0if\xc2\xa0(state.matches(\'unauthenticated\'))\xc2\xa0{\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0routes\xc2\xa0=\xc2\xa0(\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<Route\xc2\xa0path="/">\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<LoginPage\xc2\xa0service={state.children.loginMachine}\xc2\xa0/>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0</Route>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0);\n\xc2\xa0\xc2\xa0}\xc2\xa0else\xc2\xa0{\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0routes\xc2\xa0=\xc2\xa0null;\n\xc2\xa0\xc2\xa0}\n \n\xc2\xa0\xc2\xa0return\xc2\xa0(\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<BrowserRouter>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<Switch>{routes}</Switch>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0</BrowserRouter>\n\xc2\xa0\xc2\xa0);\n};\nRun Code Online (Sandbox Code Playgroud)\n在内部,HomePage 组件重定向到/contacts
// HomePage.js\nexport const HomePage = () => {\n return <Redirect to="/contacts" />;\n};\nRun Code Online (Sandbox Code Playgroud)\n现在,使用此代码,应用程序可以按照我的需要运行,但我在控制台中记录了一条警告:
\nWarning: <Route> elements should not change from controlled to uncontrolled (or vice versa). You provided a "location" prop initially but omitted it on a subsequent render.\nRun Code Online (Sandbox Code Playgroud)\n我做了一些研究,我唯一能找到的是这个/sf/answers/3677845041/,这似乎表明有条件地渲染路由导致了问题。然而,路由的条件渲染才是重点——我不希望未经身份验证的用户访问/contacts
经过一番尝试后,我将源代码修改如下:
\n// AppRoutes.js\nexport\xc2\xa0const\xc2\xa0AppRoutes\xc2\xa0=\xc2\xa0({\xc2\xa0machine\xc2\xa0})\xc2\xa0=>\xc2\xa0{\n\xc2\xa0\xc2\xa0const\xc2\xa0[state]\xc2\xa0=\xc2\xa0useMachine(machine);\n \n\xc2\xa0\xc2\xa0let\xc2\xa0routes;\n \n\xc2\xa0\xc2\xa0if\xc2\xa0(state.matches(\'authenticated\'))\xc2\xa0{\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0routes\xc2\xa0=\xc2\xa0(\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<React.Fragment>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<Route\xc2\xa0path="/home">\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<HomePage\xc2\xa0/>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0</Route>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<Route\xc2\xa0path="/contacts">\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<ContactsList\xc2\xa0/>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0</Route>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<Redirect\xc2\xa0to="/home"\xc2\xa0/>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0</React.Fragment>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0);\n\xc2\xa0\xc2\xa0}\xc2\xa0else\xc2\xa0if\xc2\xa0(state.matches(\'unauthenticated\'))\xc2\xa0{\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0routes\xc2\xa0=\xc2\xa0(\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<React.Fragment>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<Route\xc2\xa0path="/login">\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<LoginPage\xc2\xa0service={state.children.loginMachine}\xc2\xa0/>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0</Route>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<Redirect\xc2\xa0to="/login"\xc2\xa0/>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0</React.Fragment>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0);\n\xc2\xa0\xc2\xa0}\n \n\xc2\xa0\xc2\xa0return\xc2\xa0(\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<BrowserRouter>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<Switch>{routes}</Switch>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0</BrowserRouter>\n\xc2\xa0\xc2\xa0);\n};\n\n// HomePage.js\nexport const HomePage = () => {\n return <Redirect to="/contacts" />;\n};\n\nRun Code Online (Sandbox Code Playgroud)\n现在,此代码将经过身份验证的用户重定向到/contacts,并将未经身份验证的用户重定向到/login,并且不记录任何警告。
一切都很好,但我仍然不明白为什么警告不再出现,这与我之前所做的有什么不同。据我所见和理解,我正在两个版本的代码中对路线进行条件渲染。为什么一个会记录警告,而另一个则不会?
\n有什么指导吗??
\n谢谢!
\nFil*_*váč 13
根据文档: https: //reactrouter.com/web/api/Switch/children-node
a 的所有子元素都
<Switch>应该是<Route>or<Redirect>元素。
这意味着将路线包裹起来<React.Fragment></React.Fragment>或根本<></>不会切断它。
出现警告是因为这些不是<Route>元素<Redirect>。
解决方案 1:包裹<Route>另一个<Switch>
我不喜欢这个解决方案,因为你必须重复后备路由
<Switch>
<Route exact path='/' component={Main} />
{some_condition && (
<Route path='/common'>
<Switch>
<Route exact path='/common/1' component={Secondary} />
<Route exact path='/common/2' component={Ternary} />
<Route component={NotFound} /> {/* this needs to be repeated here */}
</Switch>
</Route>
)}
<Route component={NotFound} />
</Switch>
Run Code Online (Sandbox Code Playgroud)
解决方案 2:将路线渲染为数组
最终这就是我所追求的。您必须包含令人讨厌的按键,但不需要额外的元素。
<Switch>
<Route exact path='/' component={Main} />
{some_condition && [
<Route exact path='/common/1' key='/common/1' component={Secondary} />,
<Route exact path='/common/2' key='/common/2' component={Ternary} />
]}
<Route component={NotFound} />
</Switch>
Run Code Online (Sandbox Code Playgroud)
您还可以像这样格式化它:
let routes;
if (some_condition) {
routes = [
<Route exact path='/common/1' key='/common/1' component={Secondary} />,
<Route exact path='/common/2' key='/common/2' component={Ternary} />
];
}
return (
<Switch>
<Route exact path='/' component={Main} />
{routes}
<Route component={NotFound} />
</Switch>
);
Run Code Online (Sandbox Code Playgroud)
小智 1
我正在处理类似的事情。我有这个:
<Switch>
{aCondition && (
<>
<Route ... />
<Route ... />
</>
)}
Run Code Online (Sandbox Code Playgroud)
这给我带来了同样的警告。看到你的代码,我发现你也有一个片段,而在“其他”中你没有。所以我尝试了:
{aCondition ? (
<>
<Route ... />
<Route ... />
</>
) : (
<></>
)}
Run Code Online (Sandbox Code Playgroud)
而且效果很好。似乎条件片段会混淆开关。
| 归档时间: |
|
| 查看次数: |
5172 次 |
| 最近记录: |