You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Router Dom条件渲染:如何向Hero组件传递路由状态

How to Pass Route State to a Reusable Hero Component in React Router

Hey there! Let's break down how to get your current route info into that reusable Hero component, and fix a few syntax/structure issues in your existing code along the way.

First, Fix Your App Structure

Right now, you've nested a Router inside your Hero component—this is a problem because your app should only have one top-level Router (usually in your root App component). Having multiple Routers will cause routing context conflicts, and your route-related hooks won't work as expected. Let's restructure that first:

// App.js (your root component)
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import Navbar from './Navbar';
import Home from './Home';
import Consultants from './Consultants';
import Solutions from './Solutions';
import ContactUs from './ContactUs';

function App() {
  return (
    <Router>
      <Navbar /> {/* Move Navbar here—it's a global component, not part of Hero */}
      <Switch>
        <Route exact path='/' component={Home} />
        <Route exact path='/consultants' component={Consultants} />
        <Route exact path='/solutions' component={Solutions} />
        <Route exact path='/contactus' component={ContactUs} />
      </Switch>
    </Router>
  );
}

export default App;

Option 1: Pass Route Info via Props (Simplest Approach)

The most straightforward way is to grab the current route in each page component, then pass it down to Hero as a prop.

  1. Update your page components (Home, Consultants, Solutions) to use useLocation from react-router-dom:
// Home.js
import { useLocation } from 'react-router-dom';
import Hero from './Hero';

function Home() {
  const location = useLocation();
  return (
    <div>
      <Hero currentPath={location.pathname} />
      {/* Add your Home page content here */}
    </div>
  );
}

export default Home;

Repeat this pattern for Consultants.js and Solutions.js—they'll look almost identical, just rendering their own content after the Hero.

  1. Refactor the Hero component to use the passed currentPath prop:
// Hero.js
import { Fragment, useEffect } from 'react';
// Import your images (adjust paths to match your project)
import homeimg from './assets/home-hero.jpg';
import consimg from './assets/consultants-hero.jpg';
import solsimg from './assets/solutions-hero.jpg';

const Hero = ({ currentPath }) => {
  // Now this useEffect will trigger whenever the route changes
  useEffect(() => {
    console.log('Current route:', currentPath);
  }, [currentPath]);

  // Helper function to get the correct hero image
  const getHeroImage = () => {
    switch (currentPath) {
      case '/consultants':
        return consimg;
      case '/solutions':
        return solsimg;
      case '/':
      default:
        return homeimg;
    }
  };

  // Helper function to get the correct grid class
  const getHeroClass = () => {
    switch (currentPath) {
      case '/consultants':
        return 'grid-consultants';
      case '/solutions':
        return 'grid-solutions';
      case '/':
      default:
        return 'grid-home';
    }
  };

  return (
    <Fragment>
      <div className='grid-hero'>
        <div className='overlay'>
          <div>
            <p className='bg-dark'></p>
            <img 
              src={getHeroImage()} 
              alt={`Hero banner for ${currentPath === '/' ? 'Home' : currentPath.slice(1)}`} 
            />
          </div>
        </div>
      </div>
      <div className={getHeroClass()}>
        {/* Add your Hero's inner content here */}
      </div>
    </Fragment>
  );
};

export default Hero;

Option 2: Use React Context (For Scalability)

If you don't want to pass the route prop through every page component, you can create a global context to share route state across your app.

  1. Create a Route Context:
// RouteContext.js
import { createContext, useContext, useLocation } from 'react';

const RouteContext = createContext();

export const RouteProvider = ({ children }) => {
  const location = useLocation();
  return (
    <RouteContext.Provider value={{ pathname: location.pathname }}>
      {children}
    </RouteContext.Provider>
  );
};

// Custom hook to access the route context
export const useRoute = () => {
  return useContext(RouteContext);
};
  1. Wrap your app with the RouteProvider:
// App.js
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import { RouteProvider } from './RouteContext';
// ... other imports

function App() {
  return (
    <Router>
      <RouteProvider>
        <Navbar />
        <Switch>
          {/* Your routes stay the same */}
        </Switch>
      </RouteProvider>
    </Router>
  );
}
  1. Update Hero to use the custom hook:
// Hero.js
import { Fragment, useEffect } from 'react';
import { useRoute } from './RouteContext';
// ... image imports

const Hero = () => {
  const { pathname } = useRoute();

  useEffect(() => {
    console.log('Current route:', pathname);
  }, [pathname]);

  // Reuse the same getHeroImage and getHeroClass functions from Option 1, using pathname instead of currentPath

  return (
    {/* Same JSX as Option 1, using pathname to get image/class */}
  );
};

Key Fixes from Your Original Code

  • Removed the nested Router in Hero (only one Router should exist at the top)
  • Fixed the invalid img src syntax (switched to a helper function to select the correct image)
  • Fixed the invalid className syntax (used a helper function to return the correct class based on route)
  • Added currentPath/pathname to the useEffect dependency array so it triggers when the route changes

内容的提问来源于stack exchange,提问作者Mickey Gray

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 20:28:13