Search code examples
javascriptreactjsurlreact-router

Trigger a re-render when window.location.search changes


I created a button that changes my route and adds a search param to the URL.

The functionality of the button is as so:

import { Link } from "react-router-dom";

<Link to={`/route/locations?openCertainModal=true`}>
  {placeholder}
</Link>

My problem occurs when I am already in the located in /route/locations. When I click the button and I'm there, the route will change from /route/locations to /route/locations?openCertainModal=true, but since the component is already mounted, no rerender is triggered. How can I trigger a rerender of the component when ?openCertainModal=true is added to the route and window.location.search changes?

I'm using react-router-dom 5.x.x


Solution

  • Use the useSearchParams hook in the target component, when the matched route's URL path + searchParams update it should trigger a component rerender.

    Basic React-Router-DOM v6 Example:

    import { useEffect } from "react";
    import { Routes, Route, Link, useSearchParams } from "react-router-dom";
    
    const RouteLocations = () => {
      const [searchParams] = useSearchParams();
    
      ...
    
      return (
        ...
      );
    };
    
    <Route path="/route/locations" element={<RouteLocations />} />
    

    enter image description here

    Demo:

    Edit distracted-dewdney-6zlddp

    Basic React-Router-DOM v5 Example:

    Use the location.search value. It's common to abstract this logic into a custom hook.

    import { useEffect, useMemo } from "react";
    import { Switch, Route, Link, useLocation } from "react-router-dom";
    
    const useSearchParams = () => {
      const { search } = useLocation();
    
      const searchParams = useMemo(() => new URLSearchParams(search), [search]);
    
      return [searchParams];
    };
    
    const RouteLocations = () => {
      const [searchParams] = useSearchParams();
    
      useEffect(() => {
        console.log("RouteLocations rendered", searchParams.toString());
      });
    
      return (
        ...
      );
    };
    
    <Route path="/route/locations" component={RouteLocations} />
    

    Edit youthful-shockley-6qm92c