Open In App

Await Component in React Router

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

The <Await> component in React Router v6 is designed to handle the rendering of deferred values with automatic error handling. It is especially useful when dealing with asynchronous data fetching in components rendered by React Router routes. The <Await> component ensures that the rendering of components is deferred until the required data is available, providing a seamless user experience.

Awaiting

In React Router, “awaiting” typically refers to waiting for some asynchronous operation to complete before proceeding with a certain action, such as navigating to a new route or rendering a component. This often involves the await keyword in JavaScript, used with promises or asynchronous functions, to pause execution until a promise is resolved or rejected.

Syntax:

const fetchData = async () => {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Error fetching data:', error);
}
};

Type Declaration

Type declaration in React Router might refer to specifying the types of props, states, or other variables used within components or functions. This can be done using TypeScript or PropTypes to provide type safety and better documentation for the codebase. For instance, in TypeScript, you might declare the types of route parameters, state objects, or callback functions used in your components.

interface User {
id: number;
name: string;
email: string;
}

const userDetails: User = {
id: 1,
name: 'John Doe',
email: 'john@example.com'
};

Children

In React Router, “children” typically refers to the components or elements nested within a parent component, especially when dealing with nested routes. For example, in the context of <Route> components, the child component specified in the component prop or rendered within the <Route> tags is considered the “child” component.

Syntax:

import { Route, Switch } from 'react-router-dom';
import Home from './Home';
import About from './About';

const App = () => {
return (
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
);
};

errorElement

This term doesn’t have a specific meaning within React Router itself. However, it might refer to an element or component used to display error messages or handle error states within a React application that utilizes React Router. For example, you might have a designated component to render error messages when a route is not found or when an asynchronous operation fails.

Syntax:

import React from 'react';

const ErrorPage = () => {
return (
<div>
<h1>Error</h1>
<p>Oops! Something went wrong.</p>
</div>
);
};

export default ErrorPage;

Resolve

In the context of React Router, “resolve” might refer to resolving route configurations or resolving promises within route components. When defining routes, you might use route resolvers to dynamically fetch data or perform certain tasks before rendering the associated component. This can be achieved using async route components or by utilizing lifecycle methods or hooks like useEffect() to handle asynchronous operations within components.

Syntax:

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

const Profile = () => {
return (
<div>
<h1>Profile Page</h1>
{/* Render profile information */}
</div>
);
};

const ProfileRoute = () => {
const fetchData = async () => {
// Fetch user profile data
};

useEffect(() => {
fetchData();
}, []);

return <Route path="/profile" component={Profile} />;
};

export default ProfileRoute;

Features of Await in React Router:

  • Automatic error handling: <Await> component automatically handles errors that occur during the resolution of the provided promise, allowing for seamless error handling without extra boilerplate code.
  • Lazy loading and code splitting: Helps lazy loading of components to improve initial loading times and performance by loading components only when they are needed.
  • Customizable error handling UI: Provides flexibility to define custom error handling UI using the errorElement prop, allowing for contextual error messages or fallback UI.
  • Support for asynchronous data fetching: Provides asynchronous data fetching and rendering, making it easy to work with promises returned from APIs or asynchronous operations.
  • Integration with React Router: Seamlessly integrates with React Router, enabling asynchronous component rendering within the routing hierarchy, enhancing the user experience in React applications.

Steps to Implement Await in React Router App

Step 1: Create a new React App

npx create-react-app await
cd await

Step 2: Install React Router and Axios

npm install react-router-dom axios

Project Structure:

Screenshot-2024-03-21-194851

Updated dependencies in package.json will look like:

"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.6.7",
"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 example demonstrates the React Router and asynchronous data fetching using the await keyword.

Javascript
//src/App.js

import React, { Suspense } from "react";
import {
    BrowserRouter as Router,
    Routes,
    Route,
    Link,
    useParams,
} from "react-router-dom";
import { Await } from "react-router-dom";

const fetchUserData = (userId) => {
    return new Promise((resolve) => {
        setTimeout(() => {
            let userData = null;
            if (userId === "1") {
                userData = {
                    name: "Ashish",
                    email: "ashish@gmail.com",
                };
            } else if (userId === "2") {
                userData = {
                    name: "ABC",
                    email: "abc@example.com",
                };
            }
            resolve(userData);
        }, 2000);
    });
};

function UserDetails() {
    const { userId } = useParams();

    return (
        <div>
            <h1>User Details</h1>
            <Suspense fallback={<div>Loading...</div>}>
                <Await
                    resolve={fetchUserData(userId)}
                    errorElement={<div>Could not load user details 😬</div>}
                    children={(userData) => (
                        <div>
                            <p>Name: {userData.name}</p>
                            <p>Email: {userData.email}</p>
                        </div>
                    )}
                />
            </Suspense>
        </div>
    );
}

function App() {
    return (
        <Router>
            <div>
                <h1>React Router Await Example</h1>
                <nav>
                    <ul>
                        <li>
                            <Link to="/user/1">User 1</Link>
                        </li>
                        <li>
                            <Link to="/user/2">User 2</Link>
                        </li>
                    </ul>
                </nav>

                <Routes>
                    <Route path="/user/:userId" element={<UserDetails />} />
                </Routes>
            </div>
        </Router>
    );
}

export default App;
Javascript
// src/UserDetails.js

import React, { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import axios from "axios";

function UserDetails() {
    const { userId } = useParams();
    const [user, setUser] = useState(null);

    useEffect(() => {
        const fetchUserData = async () => {
            try {
                const response = await axios.get(
                    `https://jsonplaceholder.typicode.com/users/${userId}`
                );
                const userData = response.data;
                setUser(userData);
            } catch (error) {
                console.error("Error fetching user data:", error);
            }
        };

        fetchUserData();
    }, [userId]);

    if (!user) {
        return <div>Loading...</div>;
    }

    return (
        <div>
            <h1>User Details</h1>
            <p>Name: {user.name}</p>
            <p>Email: {user.email}</p>
        </div>
    );
}

export default UserDetails;
JavaScript
//src/index.js

import React from 'react';
import ReactDOM from 'react-dom/client';

import App from './App';


const root = ReactDOM.createRoot
    (document.getElementById('root'));
root.render(
    <React.StrictMode>
        <App />
    </React.StrictMode>
);

Start your application using the following command:

npm start

Output:

aw



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads