Search code examples
reactjsreact-routerreact-router-dom

REACTJS: Change loader API URL based on Rout path in React


To reuse a component that loads different data in same format, same element is rendered in different path. How to change url based on route path in EmpPage.js

App.js:

    {
    path: "emp-detail",
    element: <EmpRootLayout />,
    children: [
      {
        index: true,
        element: <EmpPage />,
        loader: empListLoader,
      },
      {
        path: "retired",
        element: <EmpPage  />,
        loader: empListLoader,
      },
      {
        path: "resigned",
        element: <EmpPage />,
        loader: empListLoader,
      },
    ],

EmpPage.js

async function loadEmpRequests() {
  // change url based on route path
  let url = "http://localhost:8000/empData";
  const response = await fetch(url, {
    method: "GET",
  });

  const resData = await response.json();
  return resData.data;
  
}

export function loader() {
  return defer({
    empRequests: loadEmpRequests(),
  });
}

Solution

  • It seems you have a lot of code duplication here. I'd suggest rendering a single route with a dynamic route parameter that can be read in the loader function.

    Example:

    {
      path: "emp-detail",
      element: <EmpRootLayout />,
      children: [
        {
          path: ":page?", // <-- optional dynamic segment
          element: <EmpPage />,
          loader: empListLoader,
        },
      ],
    }
    

    https://reactrouter.com/en/main/route/route#optional-segments

    async function loadEmpRequests({ params }) {
      const { page } = params;
    
      // change url based on route path parameter
      let url = "";
      switch(page) {
        case "retired":
          url = ".....";
          break;
    
        case "resigned":
          url = ".....";
          break;
    
        default:
          url = ".....";
          break;
    
      }
      
      const response = await fetch(url, {
        method: "GET",
      });
    
      const { data } = await response.json();
      return data;
    }
    

    An alternative might also be to make the loader a curried function and the URL can be passed in as a parameter.

    Example:

    {
      path: "emp-detail",
      element: <EmpRootLayout />,
      children: [
        {
          index: true,
          element: <EmpPage />,
          loader: empListLoader("...."),
        },
        {
          path: "retired",
          element: <EmpPage  />,
          loader: empListLoader("...."),
        },
        {
          path: "resigned",
          element: <EmpPage />,
          loader: empListLoader("...."),
        },
      ],
    }
    
    function loadEmpRequests(url) {
      return async function() {
        const response = await fetch(url, {
          method: "GET",
        });
    
        const { data } = await response.json();
        return data;
      }
    }