React Router 4 所有路由渲染同一组件的实现方案咨询
Alright, let's walk through exactly how to make every route in React Router 4 render the same component, using your provided JSON data. Here's a straightforward implementation plan with code examples:
Step 1: Set Up Dependencies
First, make sure you have react-router-dom installed (since we're using React Router 4). Then import the core components we'll need:
import React from 'react'; import { BrowserRouter as Router, Route, Link, useLocation } from 'react-router-dom';
Step 2: Create the Shared Component
We'll build a single component (let's call it ContentRenderer) that handles finding the right content from your JSON based on the current route. This component will be rendered for every route:
const ContentRenderer = ({ appData }) => { const location = useLocation(); // Split the current path into segments (e.g., "/home/dashboard" becomes ["home", "dashboard"]) const pathSegments = location.pathname.split('/').filter(segment => segment); let currentContent = '<div>404: Content Not Found</div>'; let currentLevelData = appData; // Traverse the JSON data to match the path segments for (const segment of pathSegments) { // Match the segment to a tab (we'll use lowercase for path consistency) const matchedItem = currentLevelData.find(item => item.tab.toLowerCase() === segment.toLowerCase() ); if (!matchedItem) break; // Stop if no match is found // Update content if the matched item has it if (matchedItem.content) { currentContent = matchedItem.content; } // Move to the next level of navigation if available currentLevelData = matchedItem.nav || []; } // Render the HTML content (note: only use this with trusted content to avoid XSS risks) return <div dangerouslySetInnerHTML={{ __html: currentContent }} />; };
Step 3: Configure Routes & Navigation
In your main app component, we'll set up the router, generate navigation links from your JSON, and point all routes to our shared ContentRenderer:
const App = () => { // Your provided JSON data const app = [ { tab: 'Home', nav: [ { tab: 'Dashboard', content: '<div>This is Dashboard</div>' }, { tab: 'Profile', content: '<div>This is Profile</div>' }, ] }, { tab: 'About', content: '<div>This is About</div>' }, { tab: 'Pricing', content: '<div>This is Pricing</div>' }, ]; // Recursive function to generate nested navigation links const renderNavigation = (items, parentPath = '') => { return items.map(item => { const routePath = `${parentPath}/${item.tab.toLowerCase()}`; return ( <div key={item.tab} style={{ margin: '0 10px', display: 'inline-block' }}> <Link to={routePath}>{item.tab}</Link> {/* Render sub-navigation if the item has a `nav` array */} {item.nav && ( <div style={{ marginLeft: '15px', marginTop: '5px' }}> {renderNavigation(item.nav, routePath)} </div> )} </div> ); }); }; return ( <Router> <div style={{ padding: '20px' }}> {/* Render the navigation menu */} <nav style={{ marginBottom: '20px' }}> {renderNavigation(app)} </nav> {/* All routes point to the same ContentRenderer component */} <Route path="*"> <ContentRenderer appData={app} /> </Route> </div> </Router> ); }; export default App;
Key Notes & Considerations
- Path Matching: The example uses lowercase paths for consistency, but you can adjust the matching logic to match your preferred route format (e.g., exact case matching).
- HTML Content Handling: We use
dangerouslySetInnerHTMLbecause your content is stored as HTML strings. Be cautious with this—only use it if the content is fully trusted (never with user-generated content without sanitization). - Nested Routes: The recursive
renderNavigationfunction handles nested tabs (like Home > Dashboard), and theContentRenderertraverses the nestednavarrays to find the right content. - 404 Handling: If the route doesn't match any item in your JSON, the component will show a default 404 message.
内容的提问来源于stack exchange,提问作者prgrmr

