Eflite
Eflite

Reputation: 81

React history.push() changing the browser URL, but not re-rendering the component (BrowserRouter)

I have a few navigation buttons at the bottom of the screen, and when they are clicked on, the handleClick(path) function is called, and history.push(path) is executed. This results in the browser URL to change correctly, but the component is not re-rendered, so the content corresponding to the route is not shown. I'm using BrowserRouter from react-router-dom. If I execute history.go() after the push, the component is re-rendered, but this should not be necessary. See the commented line in the code below. While my current solution works, there's clearly somthing off, and I would appreciate all answers. Thanks! :-)

import { BrowserRouter, Switch, Route, useHistory, withRouter } from 'react-router-dom';
   
function Main() {
  const [menuValue, setMenuValue] = useState();        
  const history = useHistory();

  const handleClick = (path) => {              
    history.push(path);
    history.go(); //<-- this should be unnecessary, but without it the component is not re-rendered.
  }

  return (  
    
    <div style={{ margin: '0 30%' }}>
      
      
      <p> userId={user.userId} </p>

      <BrowserRouter>
        <Switch>
          <Route exact path='/' component={Home}></Route>

          <Route path='/home' component={Home}></Route>
        
          <Route path='/chat' component={Chat}></Route>

          <Route path='/settings' component={Settings}></Route>

        </Switch>

      </BrowserRouter>

      <BottomNavigation  value={menuValue} onChange={(event, newValue) => 
        {
          setMenuValue(newValue);
        }}
      showLabels

      >
        <BottomNavigationAction onClick={_ => handleClick("/home")} label="Home" icon={<HomeIcon />} />
        <BottomNavigationAction  onClick={_ => handleClick("/chat")} label="Chat" icon={<ChatIcon />} />
        <BottomNavigationAction onClick={_ => handleClick("/settings")}label="Settings" icon={<SettingsIcon />} />

      </BottomNavigation>

    </div>

    

  );

Upvotes: 0

Views: 526

Answers (2)

Eflite
Eflite

Reputation: 81

I found out I had multiple Router-contexts, using BrowserRouter on different levels. By removing the BrowserRouter-tags in the code I posted, I now only have one router context on a higher level in my app. The history.push(path) now also causes a re-render without the need for the history.go(). That would be guaranteed to come back to bite me in the behind later.

Upvotes: 0

Naim Mustafa
Naim Mustafa

Reputation: 344

try putting BottomNavigation in Router

return (  
    
    <div style={{ margin: '0 30%' }}>
      
      
      <p> userId={user.userId} </p>

      <BrowserRouter>
        <Switch>
          <Route exact path='/' component={Home}></Route>

          <Route path='/home' component={Home}></Route>
        
          <Route path='/chat' component={Chat}></Route>

          <Route path='/settings' component={Settings}></Route>

        </Switch>

        <BottomNavigation  value={menuValue} onChange={(event, newValue) => 
            {
              setMenuValue(newValue);
             }}
            showLabels

           >
        <BottomNavigationAction onClick={_ => handleClick("/home")} 
             label="Home" icon={<HomeIcon />} />
        <BottomNavigationAction  onClick={_ => handleClick("/chat")} 
             label="Chat" icon={<ChatIcon />} />
        <BottomNavigationAction onClick={_ => 
              handleClick("/settings")}label="Settings" icon={<SettingsIcon />} />

      </BottomNavigation>

      </BrowserRouter>
    </div>

    

  );

Upvotes: 2

Related Questions