React.js中能否使用多个<Switch>?无Redux项目多层路由咨询
Absolutely! This is not only feasible but a standard pattern in React Router—you don’t need Redux at all to pull this off. Nested <Switch> components are perfect for organizing distinct sections of your app (like public vs authenticated dashboards) with their own internal routing.
Here’s how you can structure your project step by step, with code examples to illustrate:
Top-Level App Component
First, your root App component will handle the authentication state (using local React state, since Redux isn’t necessary here) and the top-level <Switch> to toggle between the public site and user dashboard. You’ll also add navigation to let users switch between these sections once logged in.
import { useState } from 'react'; import { BrowserRouter as Router, Switch, Route, Link, Redirect } from 'react-router-dom'; import PublicSite from './PublicSite'; import UserDashboard from './UserDashboard'; import Login from './Login'; // Reusable Private Route to protect authenticated routes const PrivateRoute = ({ isLoggedIn, children, ...rest }) => ( <Route {...rest} render={({ location }) => isLoggedIn ? ( children ) : ( <Redirect to={{ pathname: "/login", state: { from: location } }} /> ) } /> ); function App() { const [isLoggedIn, setIsLoggedIn] = useState(false); return ( <Router> <nav style={{ margin: '1rem 0' }}> {isLoggedIn ? ( <> <Link to="/" style={{ marginRight: '1rem' }}>Public Home</Link> <Link to="/dashboard" style={{ marginRight: '1rem' }}>User Dashboard</Link> <button onClick={() => setIsLoggedIn(false)}>Logout</button> </> ) : ( <Link to="/login">Login</Link> )} </nav> <Switch> <Route path="/login"> <Login onLogin={() => setIsLoggedIn(true)} /> </Route> {/* Public site with nested routes */} <Route path="/" exact> <PublicSite /> </Route> {/* Protected dashboard with nested routes */} <PrivateRoute path="/dashboard" isLoggedIn={isLoggedIn}> <UserDashboard /> </PrivateRoute> </Switch> </Router> ); } export default App;
Public Site Component (with its own Switch)
The PublicSite component will contain its own <Switch> to handle internal pages like Home, About, or Contact. Use the useRouteMatch hook to dynamically build nested paths so you don’t have to hardcode them.
import { Switch, Route, Link, useRouteMatch } from 'react-router-dom'; import Home from './Home'; import About from './About'; import Contact from './Contact'; function PublicSite() { const { path } = useRouteMatch(); // Grabs the current base path ("/") return ( <div> <h2>Public Website</h2> <nav style={{ margin: '1rem 0' }}> <Link to={`${path}`} style={{ marginRight: '1rem' }}>Home</Link> <Link to={`${path}/about`} style={{ marginRight: '1rem' }}>About</Link> <Link to={`${path}/contact`}>Contact</Link> </nav> <Switch> <Route path={`${path}/about`}> <About /> </Route> <Route path={`${path}/contact`}> <Contact /> </Route> <Route path={`${path}`}> <Home /> </Route> </Switch> </div> ); } export default PublicSite;
User Dashboard Component (with its own Switch)
Similarly, the UserDashboard will have its own <Switch> for internal pages like Profile, Settings, or Orders. The useRouteMatch hook here will grab the base path /dashboard to build nested routes.
import { Switch, Route, Link, useRouteMatch } from 'react-router-dom'; import Profile from './Profile'; import Settings from './Settings'; import Orders from './Orders'; function UserDashboard() { const { path } = useRouteMatch(); // Grabs the current base path ("/dashboard") return ( <div> <h2>User Dashboard</h2> <nav style={{ margin: '1rem 0' }}> <Link to={`${path}`} style={{ marginRight: '1rem' }}>Profile</Link> <Link to={`${path}/settings`} style={{ marginRight: '1rem' }}>Settings</Link> <Link to={`${path}/orders`}>My Orders</Link> </nav> <Switch> <Route path={`${path}/settings`}> <Settings /> </Route> <Route path={`${path}/orders`}> <Orders /> </Route> <Route path={`${path}`}> <Profile /> </Route> </Switch> </div> ); } export default UserDashboard;
Key Notes:
- No Redux Required: We’re using local state in
App.jsto track login status. If you need to share this state across more components later, you can easily switch to React Context instead of Redux—it’s lighter and more than sufficient for this use case. - Route Protection: The
PrivateRoutecomponent ensures that only logged-in users can access the dashboard, redirecting others to the login page. - Clean Organization: Nested switches keep your route logic separated by section, making your code easier to maintain and scale.
This structure aligns perfectly with what you’re looking to build—happy coding!
内容的提问来源于stack exchange,提问作者Amel Amcë Muminovic

