Search code examples
reactjsreact-router-dom

How to re-render the component on same routing path (Link , V6) reactjs


I have a sidebar menu to change the page

I found that the page will not trigger re-render if I clicked the menu item that is current path.

(e.g. current path is /user and click the same path /user )

when entering the page it will call useEffect to get the data, but i want to click the same link again to reload the data instead of reloading the page

I have the following React router.

 <Routes>
   <Route path="" element={<MainLayout />}>
     <Route path="/user" element={<User />} />
     <Route path="/contact" element={<Contact />} />
     <Route exact path="/" element={<Login />} />
   </Route>
</Routes>

MainLayout.jsx

<Layout>
      <Sidebar />
      <Layout>
        <Header></Header>

        <Content >
          <Outlet />
        </Content>

        <Footer >
           Sorftware
        </Footer>
      </Layout>
</Layout>

Sidebar.jsx

<Menu>
  <Menu.Item key="users" >
     <Link to="/user">User</Link>
  </Menu.Item>
</Menu>

*UPDATE : I removed index.js and CustomRouter.jsx because it doesn't seem to be related to my question


Solution

  • If you are looking for a way to trigger a route component rerender upon clicking a Link then I'd suggest using a navigation action that passes a different object, i.e. use a hash or pass some additional state, that is different on each click of the link.

    Example:

    import { Link, useNavigate } from "react-router-dom";
    import { nanoid } from "nanoid";
    
    ...
    
    const navigate = useNavigate();
    
    ...
    
    <Link
      to="/user"
      onClick={(e) => {
        e.preventDefault();
        navigate("/user", { state: nanoid() });
      }}
    >
      User
    </Link>
    

    The example here uses the Link component's to prop to provide a valid target and provide all the accessibility components. Then an onClick handler is attached to prevent the default link action from occurring so we can pass some additional state payload that is different and random each time it is invoked.

    You could use this passed state as a useEffect hook dependency if you like.

    const { state } = useLocation();
    
    useEffect(() => {
      // run side-effect
    }, [state]);
    

    Demo

    Edit how-to-re-render-the-component-on-same-routing-path-link-to-reactjs