Open In App

useLoaderData Hook in React Router

Last Updated : 01 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

useLoaderData is a hook provided by React Router. React Router is a JavaScript framework that helps to create and handle routing in React applications. This hook helps to fetch the data for the component before it renders, this improves performance and prevents empty states.

Data Fetching

Without the useLoaderData hook, we still have a way to fetch data from API.

Using a useEffect hook, which invokes when the component is rendering and at the time when its dependency changes.

useEffect( callback_functiion, [ Dependecy 1, Dependecy 2, .....])

We can implement the fetch data part inside the callback function. However, the problem with this approach is that it will run when the component is rendered. This makes it slow and may result in empty states ( component renders before data or state is fetched ).

useLoaderData( ) hook is the solution for this problem.

const data = useLoaderData( )

This basically binds the loader function and state inside our component.

When a request is made to that path, the route will invoke the loader function to fetch the data before the component renders, this will improve performance and prevent empty states.

Let us understand this using a simple example.

Steps to create React Application and module installation:

Step 1: Create a React application using the following command:

npx create-react-app redux_store

Step 2: After creating your project folder i.e. project_name, move to the folder using the following command:

cd redux_store

Step 3: Install dependencies:

npm install react-router-dom

Folder Structure:

Screenshot-2024-03-26-155322

project structure

The updated dependencies in the package.json file will look like this.

"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.22.3",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},

Example: This react app uses useLoaderData Hook to fetch the data before components render.

CSS
/* App.css */
.container {
  display: grid;
  grid-template-columns: repeat(6, 15rem);
  grid-gap: 2rem;
  grid-auto-flow: row;
}
JavaScript
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import {createBrowserRouter, RouterProvider} from 'react-router-dom';

import './index.css';
import App from './App';
import { loaderFunction } from './App';

const router = createBrowserRouter([
  {
    path: "/",
    element: <App />,
    loader:loaderFunction
  },
]);

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
   <RouterProvider router={router} />
  </React.StrictMode>
);
JavaScript
//App.js
import { useLoaderData } from 'react-router-dom';
import './App.css';
import { useEffect } from 'react';

function App() {

  const Data = useLoaderData();
  useEffect(()=>{
    console.log(Data.data[0]);
  })

  return (
    <div className='container'> 
      {Data.data.map((data,index) => (
        <div key={index} className='item'>
          <p>{ data.character.name}</p>
        <img src={data.character.images.webp.image_url} />
        </div>
        
      ))}
    </div>
  );
}

export default App;

export const loaderFunction = async ()=>{

  const response = await fetch('https://api.jikan.moe/v4/anime/20/characters');
  return await response.json();

}

Output:

Screenshot-2024-03-26-165925_11zon

Output of above code



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads