React-Router V4:如何向Route渲染函数传Props实现私有路由
Hey there! Let's work through this private route authorization and flexible prop-passing problem together. I'll break down how to validate the authorized prop in your child component and use the spread operator to keep your component reusable and extensible.
1. Build a Reusable PrivateRoute Component
First, we'll create a dedicated PrivateRoute component that handles authorization checks and prop forwarding. This keeps your route logic clean and centralized.
Here's the implementation:
import { Navigate } from 'react-router-dom'; import React from 'react'; const PrivateRoute = ({ authorized, element, ...restProps }) => { // Step 1: Validate the authorized prop if (!authorized) { // Redirect to login if not authorized (adjust the path as needed) return <Navigate to="/login" replace />; } // Step 2: Use spread operator to pass extra props to the target component // React.cloneElement lets us inject additional props into the provided element return React.cloneElement(element, { ...restProps, // Optional: Pass the authorized prop to the child component if it needs it internally authorized }); }; export default PrivateRoute;
2. Use PrivateRoute in App.js
Now in your App.js, you can use this component to wrap protected routes, passing the authorized status along with any custom props your child components need:
import { Routes, Route } from 'react-router-dom'; import PrivateRoute from './PrivateRoute'; import Dashboard from './Dashboard'; import Login from './Login'; import UserProfile from './UserProfile'; function App() { // Replace this with your actual auth state (from Context, Redux, etc.) const currentUserIsAuthorized = true; return ( <Routes> <Route path="/login" element={<Login />} /> {/* Protected Dashboard with custom props */} <Route path="/dashboard" element={ <PrivateRoute authorized={currentUserIsAuthorized} // Extra props to pass to Dashboard pageTitle="Main Dashboard" showAnalytics={true} element={<Dashboard />} /> } /> {/* Protected User Profile with different props */} <Route path="/profile" element={ <PrivateRoute authorized={currentUserIsAuthorized} // Custom props for UserProfile allowEdit={true} defaultTheme="light" element={<UserProfile />} /> } /> </Routes> ); } export default App;
Key Notes:
- Authorization Check: The
PrivateRoutedirectly checks theauthorizedprop you pass in. If it'sfalse, it redirects to the login page usingNavigatewithreplace(so the unauthorized route doesn't stay in the browser history). - Spread Operator Flexibility: The
...restPropscaptures any extra props you pass toPrivateRoute(likepageTitle,allowEdit) and injects them into the target component viaReact.cloneElement. This means you can add new props later without modifying thePrivateRouteitself. - Accessing Props in Child Components: Your
DashboardorUserProfilecomponents can now access these props directly, e.g.:// Inside Dashboard.js const Dashboard = ({ pageTitle, showAnalytics, authorized }) => { return ( <div> <h1>{pageTitle}</h1> {showAnalytics && <div>Analytics Widget</div>} </div> ); };
This setup keeps your code DRY, maintains flexibility for future props, and clearly handles authorization logic in one place.
内容的提问来源于stack exchange,提问作者KaiC

