Header component doesn't get updated after route change

Viewed 559

I am trying to understand why Header component doesn't get updated when I click Button. I believe that the problem is that I am not calling with Router. But why then App.js doesn't re render when I switch routes?

import React, { useEffect } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import First from './First';
import Second from './Second';
import Third from './Third';
import Header from './Header';

function App() {
  return (
    <div>
      <Header />
      <Router>
        <Switch>
          <Route exact path={'/'} component={First} />
          <Route exact path={'/first'} component={Second} />
          <Route exact path={'/second'} component={Third} />
        </Switch>
      </Router>
    </div>
  );
}

export default App;





import React from 'react';

export default function First(props) {
  console.log(' ~ file: First.js ~ line 4 ~ First ~ props', props);
  return (
    <div>
      First
      <button
        onClick={() => {
          props.history.push({
            pathname: '/second',
          });
        }}
      >
        Go to Second
      </button>
    </div>
  );
}

so my condition here doesn't get fired when path changes. the reason is that component hasn't been called and old condition is still there

import React from 'react'

export default function Header() {
    console.log(window.location.pathname);
    const logger = window.location.pathname === '/third' ? (<div>This is second</div>) : 
    (<div>this is root</div>)
    return logger
}

I know that I can call Header somewhere else, but what is problem in this showcase?

1 Answers

The Header component is being rendered outside the Router, so it's not rerendered or made aware of route changes.

I suggest moving the Header component into the Router and have it access the route props.

App

function App() {
  return (
    <div>
      <Router>
        <Header /> // <-- move into Router
        <Switch>
          <Route exact path={'/'} component={First} />
          <Route exact path={'/first'} component={Second} />
          <Route exact path={'/second'} component={Third} />
        </Switch>
      </Router>
    </div>
  );
}

Header

import { useLocation } from 'react-router-dom';

export default function Header() {
  const location = useLocation();

  console.log(location.pathname);

  return location.pathname === '/third' 
    ? <div>This is second</div>
    : <div>this is root</div>;
}

Edit header-component-doesnt-get-updated-after-route-change

Alternatively you could use the useRouteMatch hook:

import { useRouteMatch } from 'react-router-dom';

export default function Header() {
  const match = useRouteMatch('/third');

  return match 
    ? <div>This is second</div>
    : <div>this is root</div>;
}
Related