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评论91阅读模式
英文:

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,我猜测问题可能是路由无法推送到组件内部,但无论如何,我不知道如何解决这个问题,谢谢)

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';
    
    import { useState,useMemo, Fragment } from 'react';
    import { BrowserRouter as Route, Routes, Router } from "react-router-dom";
    
    import EmployeeDashboard from "../main-module/components/EmployeeDashboard";
    import CollapsibleTable from '../main-module/components/ClientsList';
    import EmployeeStats from '../main-module/components/EmployeeStats';
    import ProfileMenu from '../main-module/components/ProfileMenu';
    import EmployeeOptions from '../main-module/components/EmployeeOptions';
    
    const drawerWidth = 240;
    
    const StyledListItemBtn = styled(ListItemButton)(({ theme }) => ({
      borderRadius: "4px"
    }));
    
    const WorkPage = () => {
        const [component, setComponent] = useState("call");
        const [selectedIdx, setSelectedIdx] = useState(2);
    
        const handleItemClick = (idx) => {
            setSelectedIdx(idx);
        };
    
        const drawer = (
            <Box >
                <Toolbar sx={{ display: "flex", alignItems: "center", justifyContent: "space-around" }}>
                    <Typography variant='h5'>office.kr</Typography>
                </Toolbar>
                <Divider />
                    <List       
                    subheader={
                        <ListSubheader>CRM</ListSubheader>
                    }>
                        <ListItem>
                            <StyledListItemBtn 
                                selected={selectedIdx === 0} 
                                onClick={() => {setComponent("stats"); handleItemClick(0)}}
                            >
                                <ListItemIcon>
                                        <StackedLineChartIcon color='secondary'/>    
                                </ListItemIcon>
                                <ListItemText primary="Моя статистика" />
                            </StyledListItemBtn>
                        </ListItem>
                        <ListItem>
                            <StyledListItemBtn 
                                selected={selectedIdx === 1} 
                                onClick={() => {setComponent("clients"); handleItemClick(1)}}
                            >
                                <ListItemIcon>
                                        <PeopleOutlineIcon color='secondary'/>  
                                </ListItemIcon>
                                <ListItemText primary="Мои клиенты"/>
                            </StyledListItemBtn>
                        </ListItem>
                        <ListItem>
                            <StyledListItemBtn 
                                selected={selectedIdx === 2} 
                                onClick={() => {setComponent("call"); handleItemClick(2)}}
                            >
                                <ListItemIcon>
                                        <WorkOutlineIcon color='secondary'/>
                                </ListItemIcon>
                                <ListItemText primary="Обзвон" />
                            </StyledListItemBtn>
                        </ListItem>
                    </List>
                <Divider />
                <EmployeeOptions />
            </Box>
        );
        
        const setContent = () => {
            switch (component) {
                case 'call':
                    return <Route path="/dashboard" element={<EmployeeDashboard />} />;
                case 'clients':
                    return <Route path="/clients" element={<CollapsibleTable />} />;
                case 'stats':
                    return <Route path="/stats" element={<EmployeeStats />} />;
                case 'error':
                    return <p>Error</p>;
                default:
                    throw new Error('Unexpected process state');
            }
        }
    
        const elements = useMemo(() => {
            return setContent();
            // eslint-disable-next-line
        }, [component])
    
          const breadcrumbs = [
            <Link underline="hover" 
                key="1" 
                href="/" 
                sx={{ display: 'flex', alignItems: 'center' }}
            >
                <HomeIcon sx={{ mr: 1 }} fontSize="inherit" />
                Главная
            </Link>,
            <Link
                underline="hover"
                key="2"
                href="/"
            >
                CRM
            </Link>,
            <Typography key="3">
                Обзвон
            </Typography>,
        ];
    
        return (
            <Box sx={{ display: 'flex' }}>
                <CssBaseline />
                <AppBar 
                    position="fixed"         
                    sx={{
                        width: { sm: `calc(100% - ${drawerWidth}px)` },
                        ml: { sm: `${drawerWidth}px` },
                        backgroundColor: "#161b22",
                        borderBottom: "1px solid #30363d !important"
                    }}>
                    <Toolbar>
                        <Typography sx={{flexGrow: 1}} variant="h6" color="textSecondary">TestEmp</Typography>
                        <ProfileMenu sx={{flexGrow: 0}}/>
                    </Toolbar>
                </AppBar>
                <Box 
                    component="nav"
                    sx={{ width: { sm: drawerWidth }, flexShrink: { sm: 0 } }}
                >
                    <Drawer variant="temporary">
                        {drawer}
                    </Drawer>
                    <Drawer
                        variant="permanent"
                        sx={{
                            display: { xs: 'none', sm: 'block' },
                            '& .MuiDrawer-paper': { boxSizing: 'border-box', width: drawerWidth },
                        }}
                        open
                    >
                        {drawer}
                    </Drawer>
                </Box>
                <Box 
                    component="main"
                    sx={{ flexGrow: 1, p: 2.5, width: { sm: `calc(100% - ${drawerWidth}px)` } }}
                >
                    <Toolbar/>
                    <Breadcrumbs
                        separator={<NavigateNextIcon fontSize="small" />}
                        sx={{ pb: 1.5, pl: 0.5 }}
                    >
                        {breadcrumbs}
                    </Breadcrumbs>
                    <Routes>
                        {elements}
                    </Routes> 
                </Box>
            </Box>
        );
    }
    
    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';

import { useState,useMemo, Fragment } from &#39;react&#39;;
import { BrowserRouter as Route, Routes, Router } from &quot;react-router-dom&quot;;
import EmployeeDashboard from &quot;../main-module/components/EmployeeDashboard&quot;;
import CollapsibleTable from &#39;../main-module/components/ClientsList&#39;;
import EmployeeStats from &#39;../main-module/components/EmployeeStats&#39;;
import ProfileMenu from &#39;../main-module/components/ProfileMenu&#39;;
import EmployeeOptions from &#39;../main-module/components/EmployeeOptions&#39;;
const drawerWidth = 240;
const StyledListItemBtn = styled(ListItemButton)(({ theme }) =&gt; ({
borderRadius: &quot;4px&quot;
}));
const WorkPage = () =&gt; {
const [component, setComponent] = useState(&quot;call&quot;);
const [selectedIdx, setSelectedIdx] = useState(2);
const handleItemClick = (idx) =&gt; {
setSelectedIdx(idx);
};
const drawer = (
&lt;Box &gt;
&lt;Toolbar sx={{ display: &quot;flex&quot;, alignItems: &quot;center&quot;, justifyContent: &quot;space-around&quot; }}&gt;
&lt;Typography variant=&#39;h5&#39;&gt;office.kr&lt;/Typography&gt;
&lt;/Toolbar&gt;
&lt;Divider /&gt;
&lt;List       
subheader={
&lt;ListSubheader&gt;CRM&lt;/ListSubheader&gt;
}&gt;
&lt;ListItem&gt;
&lt;StyledListItemBtn 
selected={selectedIdx === 0} 
onClick={() =&gt; {setComponent(&quot;stats&quot;); handleItemClick(0)}}
&gt;
&lt;ListItemIcon&gt;
&lt;StackedLineChartIcon color=&#39;secondary&#39;/&gt;    
&lt;/ListItemIcon&gt;
&lt;ListItemText primary=&quot;Моя статистика&quot; /&gt;
&lt;/StyledListItemBtn&gt;
&lt;/ListItem&gt;
&lt;ListItem&gt;
&lt;StyledListItemBtn 
selected={selectedIdx === 1} 
onClick={() =&gt; {setComponent(&quot;clients&quot;); handleItemClick(1)}}
&gt;
&lt;ListItemIcon&gt;
&lt;PeopleOutlineIcon color=&#39;secondary&#39;/&gt;  
&lt;/ListItemIcon&gt;
&lt;ListItemText primary=&quot;Мои клиенты&quot;/&gt;
&lt;/StyledListItemBtn&gt;
&lt;/ListItem&gt;
&lt;ListItem&gt;
&lt;StyledListItemBtn 
selected={selectedIdx === 2} 
onClick={() =&gt; {setComponent(&quot;call&quot;); handleItemClick(2)}}
&gt;
&lt;ListItemIcon&gt;
&lt;WorkOutlineIcon color=&#39;secondary&#39;/&gt;
&lt;/ListItemIcon&gt;
&lt;ListItemText primary=&quot;Обзвон&quot; /&gt;
&lt;/StyledListItemBtn&gt;
&lt;/ListItem&gt;
&lt;/List&gt;
&lt;Divider /&gt;
&lt;EmployeeOptions /&gt;
&lt;/Box&gt;
);
const setContent = () =&gt; {
switch (component) {
case &#39;call&#39;:
return &lt;Route path=&quot;/dashboard&quot; element={&lt;EmployeeDashboard /&gt;} /&gt;;
case &#39;clients&#39;:
return &lt;Route path=&quot;/clients&quot; element={&lt;CollapsibleTable /&gt;} /&gt;;
case &#39;stats&#39;:
return &lt;Route path=&quot;/stats&quot; element={&lt;EmployeeStats /&gt;} /&gt;;
case &#39;error&#39;:
return &lt;p&gt;Error&lt;/p&gt;;
default:
throw new Error(&#39;Unexpected process state&#39;);
}
}
const elements = useMemo(() =&gt; {
return setContent();
// eslint-disable-next-line
}, [component])
const breadcrumbs = [
&lt;Link underline=&quot;hover&quot; 
key=&quot;1&quot; 
href=&quot;/&quot; 
sx={{ display: &#39;flex&#39;, alignItems: &#39;center&#39; }}
&gt;
&lt;HomeIcon sx={{ mr: 1 }} fontSize=&quot;inherit&quot; /&gt;
Главная
&lt;/Link&gt;,
&lt;Link
underline=&quot;hover&quot;
key=&quot;2&quot;
href=&quot;/&quot;
&gt;
CRM
&lt;/Link&gt;,
&lt;Typography key=&quot;3&quot;&gt;
Обзвон
&lt;/Typography&gt;,
];
return (
&lt;Box sx={{ display: &#39;flex&#39; }}&gt;
&lt;CssBaseline /&gt;
&lt;AppBar 
position=&quot;fixed&quot;         
sx={{
width: { sm: `calc(100% - ${drawerWidth}px)` },
ml: { sm: `${drawerWidth}px` },
backgroundColor: &quot;#161b22&quot;,
borderBottom: &quot;1px solid #30363d !important&quot;
}}&gt;
&lt;Toolbar&gt;
&lt;Typography sx={{flexGrow: 1}} variant=&quot;h6&quot; color=&quot;textSecondary&quot;&gt;TestEmp&lt;/Typography&gt;
&lt;ProfileMenu sx={{flexGrow: 0}}/&gt;
&lt;/Toolbar&gt;
&lt;/AppBar&gt;
&lt;Box 
component=&quot;nav&quot;
sx={{ width: { sm: drawerWidth }, flexShrink: { sm: 0 } }}
&gt;
&lt;Drawer variant=&quot;temporary&quot;&gt;
{drawer}
&lt;/Drawer&gt;
&lt;Drawer
variant=&quot;permanent&quot;
sx={{
display: { xs: &#39;none&#39;, sm: &#39;block&#39; },
&#39;&amp; .MuiDrawer-paper&#39;: { boxSizing: &#39;border-box&#39;, width: drawerWidth },
}}
open
&gt;
{drawer}
&lt;/Drawer&gt;
&lt;/Box&gt;
&lt;Box 
component=&quot;main&quot;
sx={{ flexGrow: 1, p: 2.5, width: { sm: `calc(100% - ${drawerWidth}px)` } }}
&gt;
&lt;Toolbar/&gt;
&lt;Breadcrumbs
separator={&lt;NavigateNextIcon fontSize=&quot;small&quot; /&gt;}
sx={{ pb: 1.5, pl: 0.5 }}
&gt;
{breadcrumbs}
&lt;/Breadcrumbs&gt;
&lt;Routes&gt;
{elements}
&lt;/Routes&gt; 
&lt;/Box&gt;
&lt;/Box&gt;
);
}
export default WorkPage;

答案1

得分: 0

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

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

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

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

<BrowserRouter>
  <Routes>
    <Route path="/" element={<div>Hello World</div>} />
  </Routes>
</BrowserRouter>

不要这样做:

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:

&lt;BrowserRouter&gt;
&lt;Routes&gt;
&lt;Route path=&quot;/&quot; element={&lt;div&gt;Hello World&lt;/div&gt;} /&gt;
&lt;/Routes&gt;
&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:

确定