React路由切换组件仅刷新生效,导航跳转无响应问题求助
Hey there, let's break down why your component switching only works on page refresh and not when navigating via links—this is a common gotcha with React Router!
The Root Problem
You've wrapped your App component with withRouter, but you're rendering the <Router> inside the App component's render method. Here's why that breaks things:
withRouterrelies on theRoutercontext to inject updated route props (likelocation) when the route changes.- Since your
Appcomponent is the parent of<Router>, it doesn't exist within the Router's context. That means when you navigate,Appnever gets notified of the route change—only the initiallocationis injected on page refresh, so your conditional rendering doesn't trigger.
The Fix
Let's rearrange your component structure to get App inside the Router context properly.
Step 1: Move <Router> to Wrap App (in your entry file, e.g., index.js)
Instead of rendering <Router> inside App, wrap your entire App component with it at the root level:
import React from 'react'; import ReactDOM from 'react-dom/client'; import { BrowserRouter as Router } from 'react-router-dom'; import App from './App'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <Router> <App /> </Router> );
Step 2: Update App Component to Remove Internal <Router>
Now that App is inside the Router context, withRouter will correctly inject updated location props when the route changes. Your App component should look like this:
import { withRouter } from "react-router-dom"; class App extends Component { render() { return ( <div className="App"> pathname: {this.props.location.pathname} {!this.props.location.pathname.includes('/target') ? <TopBar childProps={childProps} /> : null} {!this.props.location.pathname.includes('/target') ? <Header /> : null} {this.props.location.pathname.includes('/target') ? <SecondaryHeader /> : null} <Routes childProps={childProps} /> <Footer /> </div> ) } } export default withRouter(App);
Bonus: If You're Using React Router v6+
Note that withRouter was removed in v6. For class components, you'd need to create a custom HOC to inject route props, but switching to a function component with hooks is cleaner:
import { useLocation } from "react-router-dom"; function App() { const location = useLocation(); return ( <div className="App"> pathname: {location.pathname} {!location.pathname.includes('/target') && <TopBar childProps={childProps} />} {!location.pathname.includes('/target') && <Header />} {location.pathname.includes('/target') && <SecondaryHeader />} <Routes childProps={childProps} /> <Footer /> </div> ); } export default App;
This way, useLocation will automatically update whenever the route changes, triggering a re-render of your conditional components.
内容的提问来源于stack exchange,提问作者Dejan.S

