React Router V4 受保护路由:Flux架构下Props传递与权限控制问询
Hey there! Let's walk through how to set up both public (unauthenticated) and protected (authenticated-only) routes in your Flux-based React app built with create-react-app. We'll lean into your existing Flux setup to pass auth state through props and enforce route access rules.
1. First, Make Sure Your Auth Store Tracks Authentication State
Your Flux Auth Store needs to keep track of whether a user is logged in, and emit changes when that state updates. Here's a simplified example of what that might look like:
// stores/AuthStore.js import { EventEmitter } from 'events'; class AuthStore extends EventEmitter { _isAuthenticated = false; // Getter to expose the auth state getIsAuthenticated() { return this._isAuthenticated; } // Update state when user logs in handleLoginSuccess() { this._isAuthenticated = true; this.emit('change'); // Trigger a state update for listening components } // Update state when user logs out handleLogout() { this._isAuthenticated = false; this.emit('change'); } } export default new AuthStore();
2. Build a Reusable Protected Route Component
Create a wrapper component that checks the auth state before rendering a protected route. If the user isn't authenticated, it'll redirect them to the login page:
// components/ProtectedRoute.js import React from 'react'; import { Route, Redirect } from 'react-router-dom'; const ProtectedRoute = ({ component: Component, isAuthenticated, ...rest }) => { return ( <Route {...rest} render={(props) => isAuthenticated ? ( <Component {...props} /> ) : ( <Redirect to="/login" /> ) } /> ); }; export default ProtectedRoute;
3. Wire Up Routes in Your Root Component
In your main App.js (or root component), listen for changes in the Auth Store, keep the auth state in the component's state, and define your public vs protected routes:
// App.js import React, { Component } from 'react'; import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'; import ProtectedRoute from './components/ProtectedRoute'; import AuthStore from './stores/AuthStore'; import Home from './components/Home'; // Public route import Login from './components/Login'; // Public route import Dashboard from './components/Dashboard'; // Protected route import Profile from './components/Profile'; // Protected route class App extends Component { state = { isAuthenticated: AuthStore.getIsAuthenticated(), }; componentDidMount() { // Listen for auth state changes from the Flux Store AuthStore.on('change', this.updateAuthState); } componentWillUnmount() { // Clean up the listener to avoid memory leaks AuthStore.removeListener('change', this.updateAuthState); } updateAuthState = () => { this.setState({ isAuthenticated: AuthStore.getIsAuthenticated(), }); }; render() { const { isAuthenticated } = this.state; return ( <Router> <Switch> {/* Public routes - no auth required */} <Route exact path="/" component={Home} /> <Route path="/login" component={Login} /> {/* Protected routes - only accessible if authenticated */} <ProtectedRoute path="/dashboard" component={Dashboard} isAuthenticated={isAuthenticated} /> <ProtectedRoute path="/profile" component={Profile} isAuthenticated={isAuthenticated} /> {/* Catch-all 404 route */} <Route component={() => <h1>404 - Page Not Found</h1>} /> </Switch> </Router> ); } } export default App;
4. Connect Login/Logout Actions to the Store
Make sure your auth actions trigger updates in the Auth Store. For example, when a user successfully logs in:
// actions/AuthActions.js import AuthStore from '../stores/AuthStore'; export const loginUser = (credentials) => { // Replace with your actual login logic (API call, etc.) const loginSuccess = true; // Simulate successful login if (loginSuccess) { AuthStore.handleLoginSuccess(); } }; export const logoutUser = () => { AuthStore.handleLogout(); };
You can call these actions from your Login/Logout components to toggle the auth state, which will automatically update the routes.
Key Notes
- State Sync: The root component listens for changes in the Auth Store, so any login/logout action will immediately update the route access rules.
- Reusability: The
ProtectedRoutecomponent encapsulates the auth check logic, so you don't have to repeat it for every protected page. - Props Flow: Since you're already passing Flux store state through props, this setup fits seamlessly with your existing architecture.
内容的提问来源于stack exchange,提问作者Rob

