Search code examples
reactjsreact-routerreact-router-domhrefi18next

How to don't rerender root app component after every <a href> from menu (with BrowserRouter/Switch)


I'm beginner in frontend/React, and I've found problem in my application. So we have 3 components:

App (root) -> Application -> Menu

And if I choose tab from Menu it every time rerender App component (I have init function there, and it's reinit after every click something in Menu). How could I change my code, to don't do that (I've tried useMemo in App, but it didn't work, so I think something with my Menu code isn't correct).

App(root):

const App = () => {

  i18next.init({(...)});

  return (
    <I18nextProvider i18n={i18next}>
      <OtherProviders>
         <Application />
      </OtherProviders>
    </I18nextProvider>
  );
}

export default App;

Application:

const Application = () => {
(...logic...)
return (
    <div>
        <div ref={node}>
            <FocusLock disabled={!open}>
                <Burger/>
                <Menu/>
            </FocusLock>
        </div>
        <BrowserRouter>
            <Switch>
                <Route path="/page1">
                    <Comp1/>
                </Route>
                <Route path="/page2"> 
                    <Comp2/>
                </Route>
            </Switch>
        </BrowserRouter>
    </div>
  );
}

export default Application;

Menu:

const Menu = () => {
  (...logic...)
  return (
    <StyledMenu>
      <a href="/page1" tabIndex={tabIndex}>
        <span aria-hidden="true">1</span>
        {t('menu.page1')}
      </a>
      <a href="/page2" tabIndex={tabIndex}>
        <span aria-hidden="true">2</span>
        {t('menu.page2')}
      </a>
    </StyledMenu>
  )
}

export default Menu;

And after every click on

<a href ...>

in menu my application reload all app, including component, so in every click on menu href i18next is reinitializated. What's wrong here, and how to change that behaviour?

EDIT: You're right. I tried this, but wasn't in , so additionally I had to change code to:

<BrowserRouter>
    <div ref={node}>
        <FocusLock disabled={!open}>
            <Burger/>
            <Menu/>
        </FocusLock>
    </div>
    <div>
        <Switch>
            <Route path="/page1">
                <Comp1/>
            </Route>
            <Route path="/page2"> 
                <Comp2/>
            </Route>
        </Switch>
    </div>
</BrowserRouter>

After that everything working correctly.


Solution

  • Don't use <a href... that triggers an html load of a new uri

    Instead use something like Link from react-router-dom

    <Link to="/">...</Link