Almas
Almas

Reputation: 73

is there a way to invoke loader method from within the component in react

I am using a loader from react-router-dom to fetch data to be used in the component. I also have another function from within the component which updates some information which are initially fetched by the loader function. Is there a way to recall the loader function after the component is rendered so that i can get the latest data after updating.

Upvotes: 1

Views: 1881

Answers (2)

Keepvogel
Keepvogel

Reputation: 1

As Drew mentioned, the most straightforward way to trigger the loader again is to structure the function that changes the data in such a way that React Router revalidates the data automatically.

There are several instances where data is revalidated, keeping your UI in sync with your data automatically:

  • After an action is called from a .
  • After an action is called from a <fetcher.Form>
  • After an action is called from useSubmit
  • After an action is called from a fetcher.submit
  • When an explicit revalidation is triggered via useRevalidator
  • When the URL params change for an already rendered route
  • When the URL Search params change
  • When navigating to the same URL as the current URL

You don't mention how the data is updated, but you might just be able to use React Router's Form.

You can also use useRevalidator.

This hook allows you to revalidate the data for any reason. React Router automatically revalidates the data after actions are called, but you may want to revalidate for other reasons like when focus returns to the window.

Again, React Router already revalidates the data on the page automatically in the vast majority of cases so this should rarely be needed. If you find yourself using this for normal CRUD operations on your data in response to user interactions, you're probably not taking advantage of the other APIs like , useSubmit, or useFetcher that do this automatically.

Upvotes: 0

Drew Reese
Drew Reese

Reputation: 203373

Routes run some logic to first check if their fetched data should be revalidated, e.g. rerun the route loaders under several conditions.

See shouldRevalidate for details.

There's a list for what triggers automatic revalidation, I've emphasized the one that may be of interest to your use case:

There are several instances where data is revalidated, keeping your UI in sync with your data automatically:

  • After an action is called from a .
  • After an action is called from a <fetcher.Form>
  • After an action is called from useSubmit
  • After an action is called from a fetcher.submit
  • When the URL params change for an already rendered route
  • When the URL Search params change
  • When navigating to the same URL as the current URL

You could simply trigger a navigation action to the current route and that route's loader function will be run again.

import { useNavigate } from 'react-router-dom';

...

const navigate = useNavigate();

...

// "Redirect" to current route path
navigate(".", { replace: true });

Demo

Edit is-there-a-way-to-invoke-loader-method-from-within-the-component-in-react

Code:

import { useEffect } from "react";
import {
  createBrowserRouter,
  RouterProvider,
  useNavigate
} from "react-router-dom";

const Home = () => {
  const navigate = useNavigate();

  useEffect(() => {
    console.log("Mounting useEffect, will trigger data refetch in 5 seconds");

    const timer = setTimeout(navigate, 5000, ".", { replace: true });
    return () => {
      clearTimeout(timer);
    };
  }, []);

  return (
    <>
      <h1>Home</h1>
      <button type="button" onClick={() => navigate(".", { replace: true })}>
        Manual reload data
      </button>
    </>
  );
};

const router = createBrowserRouter([
  {
    path: "/",
    element: <Home />,
    loader: () => {
      console.log("loading data");
      return null;
    }
  }
]);

export default function App() {
  return <RouterProvider router={router} />;
}

Upvotes: 1

Related Questions