BrowserRouter is not a <Route> component. All component children of <Routes>must be a<Route>or<React.Fragment>router component already exist in App.js

huangapple go评论125阅读模式
英文:

BrowserRouter is not a <Route> component. All component children of <Routes>must be a<Route>or<React.Fragment>router component already exist in App.js

问题

在创建我的CRM系统时,遇到了React Router中与组件渲染错误有关的bug,我猜测问题可能是路由无法推送到组件内部,但无论如何,我不知道如何解决这个问题,谢谢)

  1. import {AppBar,
  2. Box,
  3. CssBaseline,
  4. Divider,
  5. Drawer,
  6. List,
  7. ListItem,
  8. ListItemButton,
  9. ListItemIcon,
  10. ListItemText,
  11. Toolbar,
  12. Typography,
  13. ListSubheader,
  14. Breadcrumbs,
  15. Link, styled} from '@mui/material'
  16. import StackedLineChartIcon from '@mui/icons-material/StackedLineChart';
  17. import PeopleOutlineIcon from '@mui/icons-material/PeopleOutline';
  18. import WorkOutlineIcon from '@mui/icons-material/WorkOutline';
  19. import NavigateNextIcon from '@mui/icons-material/NavigateNext';
  20. import HomeIcon from '@mui/icons-material/Home';
  21. import { useState,useMemo, Fragment } from 'react';
  22. import { BrowserRouter as Route, Routes, Router } from "react-router-dom";
  23. import EmployeeDashboard from "../main-module/components/EmployeeDashboard";
  24. import CollapsibleTable from '../main-module/components/ClientsList';
  25. import EmployeeStats from '../main-module/components/EmployeeStats';
  26. import ProfileMenu from '../main-module/components/ProfileMenu';
  27. import EmployeeOptions from '../main-module/components/EmployeeOptions';
  28. const drawerWidth = 240;
  29. const StyledListItemBtn = styled(ListItemButton)(({ theme }) => ({
  30. borderRadius: "4px"
  31. }));
  32. const WorkPage = () => {
  33. const [component, setComponent] = useState("call");
  34. const [selectedIdx, setSelectedIdx] = useState(2);
  35. const handleItemClick = (idx) => {
  36. setSelectedIdx(idx);
  37. };
  38. const drawer = (
  39. <Box >
  40. <Toolbar sx={{ display: "flex", alignItems: "center", justifyContent: "space-around" }}>
  41. <Typography variant='h5'>office.kr</Typography>
  42. </Toolbar>
  43. <Divider />
  44. <List
  45. subheader={
  46. <ListSubheader>CRM</ListSubheader>
  47. }>
  48. <ListItem>
  49. <StyledListItemBtn
  50. selected={selectedIdx === 0}
  51. onClick={() => {setComponent("stats"); handleItemClick(0)}}
  52. >
  53. <ListItemIcon>
  54. <StackedLineChartIcon color='secondary'/>
  55. </ListItemIcon>
  56. <ListItemText primary="Моя статистика" />
  57. </StyledListItemBtn>
  58. </ListItem>
  59. <ListItem>
  60. <StyledListItemBtn
  61. selected={selectedIdx === 1}
  62. onClick={() => {setComponent("clients"); handleItemClick(1)}}
  63. >
  64. <ListItemIcon>
  65. <PeopleOutlineIcon color='secondary'/>
  66. </ListItemIcon>
  67. <ListItemText primary="Мои клиенты"/>
  68. </StyledListItemBtn>
  69. </ListItem>
  70. <ListItem>
  71. <StyledListItemBtn
  72. selected={selectedIdx === 2}
  73. onClick={() => {setComponent("call"); handleItemClick(2)}}
  74. >
  75. <ListItemIcon>
  76. <WorkOutlineIcon color='secondary'/>
  77. </ListItemIcon>
  78. <ListItemText primary="Обзвон" />
  79. </StyledListItemBtn>
  80. </ListItem>
  81. </List>
  82. <Divider />
  83. <EmployeeOptions />
  84. </Box>
  85. );
  86. const setContent = () => {
  87. switch (component) {
  88. case 'call':
  89. return <Route path="/dashboard" element={<EmployeeDashboard />} />;
  90. case 'clients':
  91. return <Route path="/clients" element={<CollapsibleTable />} />;
  92. case 'stats':
  93. return <Route path="/stats" element={<EmployeeStats />} />;
  94. case 'error':
  95. return <p>Error</p>;
  96. default:
  97. throw new Error('Unexpected process state');
  98. }
  99. }
  100. const elements = useMemo(() => {
  101. return setContent();
  102. // eslint-disable-next-line
  103. }, [component])
  104. const breadcrumbs = [
  105. <Link underline="hover"
  106. key="1"
  107. href="/"
  108. sx={{ display: 'flex', alignItems: 'center' }}
  109. >
  110. <HomeIcon sx={{ mr: 1 }} fontSize="inherit" />
  111. Главная
  112. </Link>,
  113. <Link
  114. underline="hover"
  115. key="2"
  116. href="/"
  117. >
  118. CRM
  119. </Link>,
  120. <Typography key="3">
  121. Обзвон
  122. </Typography>,
  123. ];
  124. return (
  125. <Box sx={{ display: 'flex' }}>
  126. <CssBaseline />
  127. <AppBar
  128. position="fixed"
  129. sx={{
  130. width: { sm: `calc(100% - ${drawerWidth}px)` },
  131. ml: { sm: `${drawerWidth}px` },
  132. backgroundColor: "#161b22",
  133. borderBottom: "1px solid #30363d !important"
  134. }}>
  135. <Toolbar>
  136. <Typography sx={{flexGrow: 1}} variant="h6" color="textSecondary">TestEmp</Typography>
  137. <ProfileMenu sx={{flexGrow: 0}}/>
  138. </Toolbar>
  139. </AppBar>
  140. <Box
  141. component="nav"
  142. sx={{ width: { sm: drawerWidth }, flexShrink: { sm: 0 } }}
  143. >
  144. <Drawer variant="temporary">
  145. {drawer}
  146. </Drawer>
  147. <Drawer
  148. variant="permanent"
  149. sx={{
  150. display: { xs: 'none', sm: 'block' },
  151. '& .MuiDrawer-paper': { boxSizing: 'border-box', width: drawerWidth },
  152. }}
  153. open
  154. >
  155. {drawer}
  156. </Drawer>
  157. </Box>
  158. <Box
  159. component="main"
  160. sx={{ flexGrow: 1, p: 2.5, width: { sm: `calc(100% - ${drawerWidth}px)` } }}
  161. >
  162. <Toolbar/>
  163. <Breadcrumbs
  164. separator={<NavigateNextIcon fontSize="small" />}
  165. sx={{ pb: 1.5, pl: 0.5 }}
  166. >
  167. {breadcrumbs}
  168. </Breadcrumbs>
  169. <Routes>
  170. {elements}
  171. </Routes>
  172. </Box>
  173. </Box>
  174. );
  175. }
  176. export default WorkPage;
英文:

Creating my own CRM system, encountered a bug in React Router which is related to component rendering error, I guess the problem is that routes cannot be pushed inside components, anyway I don't know how to solve this problem, thanks)
import {AppBar,
Box,
CssBaseline,
Divider,
Drawer,
List,
ListItem,
ListItemButton,
ListItemIcon,
ListItemText,
Toolbar,
Typography,
ListSubheader,
Breadcrumbs,
Link, styled} from '@mui/material'
import StackedLineChartIcon from '@mui/icons-material/StackedLineChart';
import PeopleOutlineIcon from '@mui/icons-material/PeopleOutline';
import WorkOutlineIcon from '@mui/icons-material/WorkOutline';
import NavigateNextIcon from '@mui/icons-material/NavigateNext';
import HomeIcon from '@mui/icons-material/Home';

  1. import { useState,useMemo, Fragment } from &#39;react&#39;;
  2. import { BrowserRouter as Route, Routes, Router } from &quot;react-router-dom&quot;;
  3. import EmployeeDashboard from &quot;../main-module/components/EmployeeDashboard&quot;;
  4. import CollapsibleTable from &#39;../main-module/components/ClientsList&#39;;
  5. import EmployeeStats from &#39;../main-module/components/EmployeeStats&#39;;
  6. import ProfileMenu from &#39;../main-module/components/ProfileMenu&#39;;
  7. import EmployeeOptions from &#39;../main-module/components/EmployeeOptions&#39;;
  8. const drawerWidth = 240;
  9. const StyledListItemBtn = styled(ListItemButton)(({ theme }) =&gt; ({
  10. borderRadius: &quot;4px&quot;
  11. }));
  12. const WorkPage = () =&gt; {
  13. const [component, setComponent] = useState(&quot;call&quot;);
  14. const [selectedIdx, setSelectedIdx] = useState(2);
  15. const handleItemClick = (idx) =&gt; {
  16. setSelectedIdx(idx);
  17. };
  18. const drawer = (
  19. &lt;Box &gt;
  20. &lt;Toolbar sx={{ display: &quot;flex&quot;, alignItems: &quot;center&quot;, justifyContent: &quot;space-around&quot; }}&gt;
  21. &lt;Typography variant=&#39;h5&#39;&gt;office.kr&lt;/Typography&gt;
  22. &lt;/Toolbar&gt;
  23. &lt;Divider /&gt;
  24. &lt;List
  25. subheader={
  26. &lt;ListSubheader&gt;CRM&lt;/ListSubheader&gt;
  27. }&gt;
  28. &lt;ListItem&gt;
  29. &lt;StyledListItemBtn
  30. selected={selectedIdx === 0}
  31. onClick={() =&gt; {setComponent(&quot;stats&quot;); handleItemClick(0)}}
  32. &gt;
  33. &lt;ListItemIcon&gt;
  34. &lt;StackedLineChartIcon color=&#39;secondary&#39;/&gt;
  35. &lt;/ListItemIcon&gt;
  36. &lt;ListItemText primary=&quot;Моя статистика&quot; /&gt;
  37. &lt;/StyledListItemBtn&gt;
  38. &lt;/ListItem&gt;
  39. &lt;ListItem&gt;
  40. &lt;StyledListItemBtn
  41. selected={selectedIdx === 1}
  42. onClick={() =&gt; {setComponent(&quot;clients&quot;); handleItemClick(1)}}
  43. &gt;
  44. &lt;ListItemIcon&gt;
  45. &lt;PeopleOutlineIcon color=&#39;secondary&#39;/&gt;
  46. &lt;/ListItemIcon&gt;
  47. &lt;ListItemText primary=&quot;Мои клиенты&quot;/&gt;
  48. &lt;/StyledListItemBtn&gt;
  49. &lt;/ListItem&gt;
  50. &lt;ListItem&gt;
  51. &lt;StyledListItemBtn
  52. selected={selectedIdx === 2}
  53. onClick={() =&gt; {setComponent(&quot;call&quot;); handleItemClick(2)}}
  54. &gt;
  55. &lt;ListItemIcon&gt;
  56. &lt;WorkOutlineIcon color=&#39;secondary&#39;/&gt;
  57. &lt;/ListItemIcon&gt;
  58. &lt;ListItemText primary=&quot;Обзвон&quot; /&gt;
  59. &lt;/StyledListItemBtn&gt;
  60. &lt;/ListItem&gt;
  61. &lt;/List&gt;
  62. &lt;Divider /&gt;
  63. &lt;EmployeeOptions /&gt;
  64. &lt;/Box&gt;
  65. );
  66. const setContent = () =&gt; {
  67. switch (component) {
  68. case &#39;call&#39;:
  69. return &lt;Route path=&quot;/dashboard&quot; element={&lt;EmployeeDashboard /&gt;} /&gt;;
  70. case &#39;clients&#39;:
  71. return &lt;Route path=&quot;/clients&quot; element={&lt;CollapsibleTable /&gt;} /&gt;;
  72. case &#39;stats&#39;:
  73. return &lt;Route path=&quot;/stats&quot; element={&lt;EmployeeStats /&gt;} /&gt;;
  74. case &#39;error&#39;:
  75. return &lt;p&gt;Error&lt;/p&gt;;
  76. default:
  77. throw new Error(&#39;Unexpected process state&#39;);
  78. }
  79. }
  80. const elements = useMemo(() =&gt; {
  81. return setContent();
  82. // eslint-disable-next-line
  83. }, [component])
  84. const breadcrumbs = [
  85. &lt;Link underline=&quot;hover&quot;
  86. key=&quot;1&quot;
  87. href=&quot;/&quot;
  88. sx={{ display: &#39;flex&#39;, alignItems: &#39;center&#39; }}
  89. &gt;
  90. &lt;HomeIcon sx={{ mr: 1 }} fontSize=&quot;inherit&quot; /&gt;
  91. Главная
  92. &lt;/Link&gt;,
  93. &lt;Link
  94. underline=&quot;hover&quot;
  95. key=&quot;2&quot;
  96. href=&quot;/&quot;
  97. &gt;
  98. CRM
  99. &lt;/Link&gt;,
  100. &lt;Typography key=&quot;3&quot;&gt;
  101. Обзвон
  102. &lt;/Typography&gt;,
  103. ];
  104. return (
  105. &lt;Box sx={{ display: &#39;flex&#39; }}&gt;
  106. &lt;CssBaseline /&gt;
  107. &lt;AppBar
  108. position=&quot;fixed&quot;
  109. sx={{
  110. width: { sm: `calc(100% - ${drawerWidth}px)` },
  111. ml: { sm: `${drawerWidth}px` },
  112. backgroundColor: &quot;#161b22&quot;,
  113. borderBottom: &quot;1px solid #30363d !important&quot;
  114. }}&gt;
  115. &lt;Toolbar&gt;
  116. &lt;Typography sx={{flexGrow: 1}} variant=&quot;h6&quot; color=&quot;textSecondary&quot;&gt;TestEmp&lt;/Typography&gt;
  117. &lt;ProfileMenu sx={{flexGrow: 0}}/&gt;
  118. &lt;/Toolbar&gt;
  119. &lt;/AppBar&gt;
  120. &lt;Box
  121. component=&quot;nav&quot;
  122. sx={{ width: { sm: drawerWidth }, flexShrink: { sm: 0 } }}
  123. &gt;
  124. &lt;Drawer variant=&quot;temporary&quot;&gt;
  125. {drawer}
  126. &lt;/Drawer&gt;
  127. &lt;Drawer
  128. variant=&quot;permanent&quot;
  129. sx={{
  130. display: { xs: &#39;none&#39;, sm: &#39;block&#39; },
  131. &#39;&amp; .MuiDrawer-paper&#39;: { boxSizing: &#39;border-box&#39;, width: drawerWidth },
  132. }}
  133. open
  134. &gt;
  135. {drawer}
  136. &lt;/Drawer&gt;
  137. &lt;/Box&gt;
  138. &lt;Box
  139. component=&quot;main&quot;
  140. sx={{ flexGrow: 1, p: 2.5, width: { sm: `calc(100% - ${drawerWidth}px)` } }}
  141. &gt;
  142. &lt;Toolbar/&gt;
  143. &lt;Breadcrumbs
  144. separator={&lt;NavigateNextIcon fontSize=&quot;small&quot; /&gt;}
  145. sx={{ pb: 1.5, pl: 0.5 }}
  146. &gt;
  147. {breadcrumbs}
  148. &lt;/Breadcrumbs&gt;
  149. &lt;Routes&gt;
  150. {elements}
  151. &lt;/Routes&gt;
  152. &lt;/Box&gt;
  153. &lt;/Box&gt;
  154. );
  155. }
  156. export default WorkPage;

答案1

得分: 0

问题在于您将BrowserRouter用作Route,这是不正确的。BrowserRouter应该用作Routes的包装,而Routes则是Route的包装。

通常,您会像这样导入三个模块:

  1. import { BrowserRouter, Route, Routes } from "react-router-dom";

然后在您的应用程序中的某个地方定义它们:

  1. <BrowserRouter>
  2. <Routes>
  3. <Route path="/" element={<div>Hello World</div>} />
  4. </Routes>
  5. </BrowserRouter>

不要这样做:

  1. import { BrowserRouter as Route, ... }
英文:

The issue is you're using BrowserRouter as a Route which is incorrect. That's meant to be a wrapper for Routes which is a wrapper for Route.

Typically you would bring in 3 imports like this:

import { BrowserRouter, Route, Routes } from &quot;react-router-dom&quot;;

Then inside your app somewhere define them:

  1. &lt;BrowserRouter&gt;
  2. &lt;Routes&gt;
  3. &lt;Route path=&quot;/&quot; element={&lt;div&gt;Hello World&lt;/div&gt;} /&gt;
  4. &lt;/Routes&gt;
  5. &lt;/BrowserRouter&gt;

Don't do this:

import { BrowserRouter as Route, ... }

huangapple
  • 本文由 发表于 2023年2月23日 21:19:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75545399.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定