State Management at Route Level
Provide an example of encapsulating local state within a route component, and how to fetch data upon entering a route using useEffect hook, ensuring the state is tightly coupled with the route lifecycle.
import React, { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
function UserDetails() {
const { userId } = useParams();
const [userDetails, setUserDetails] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
setIsLoading(true);
fetch(`https://api.example.com/users/${userId}`)
.then(response => {
if (!response.ok) {
throw new Error('Failed to fetch');
}
return response.json();
})
.then(data => setUserDetails(data))
.catch(err => setError(err.toString()))
.finally(() => setIsLoading(false));
}, [userId]);
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
return (
<div>
<h1>User Details</h1>
{userDetails && <pre>{JSON.stringify(userDetails, null, 2)}</pre>}
</div>
);
}
export default UserDetails;
This code snippet demonstrates how to manage state within a route component in React. Here, `UserDetails` is a functional component that fetches and displays details of a user based on the `userId` obtained from the URL parameters using `useParams` hook from `react-router-dom`. `useState` is used to manage the user details data, loading state, and any potential errors. `useEffect` is hooked into the component's lifecycle to fetch data when the component mounts or when `userId` changes. The fetch request's loading state, response handling, and error handling are all encapsulated within this component, making the state management tightly coupled with the route's lifecycle.