Fetch and Display Data
a) Using the Fetch API:
The Fetch API is built into modern browsers and provides a powerful and flexible way to make HTTP requests.
Example using Fetch:
import React, { useState, useEffect } from "react";
function UserList() { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null);
useEffect(() => { fetch("https://jsonplaceholder.typicode.com/users") .then((response) => { if (!response.ok) { throw new Error("Network response was not ok"); } return response.json(); }) .then((data) => { setUsers(data); setLoading(false); }) .catch((error) => { setError(error.message); setLoading(false); }); }, []);
if (loading) return <div>Loading...</div>; if (error) return <div>Error: {error}</div>;
return ( <ul> {users.map((user) => ( <li key={user.id}>{user.name}</li> ))} </ul> );}
export default UserList;
Key points:
- We use the
useEffect
hook to fetch data when the component mounts. - We handle loading and error states.
- The fetch call returns a Promise that we resolve to get the data.
b) Using Axios:
Axios is a popular third-party library for making HTTP requests. It provides an easy-to-use API and some additional features over the Fetch API.
First, install Axios:
npm install axios
Example using Axios:
import React, { useState, useEffect } from "react";import axios from "axios";
function UserList() { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null);
useEffect(() => { axios .get("https://jsonplaceholder.typicode.com/users") .then((response) => { setUsers(response.data); setLoading(false); }) .catch((error) => { setError(error.message); setLoading(false); }); }, []);
if (loading) return <div>Loading...</div>; if (error) return <div>Error: {error}</div>;
return ( <ul> {users.map((user) => ( <li key={user.id}>{user.name}</li> ))} </ul> );}
export default UserList;
Key points:
- Axios automatically transforms the response to JSON.
- It provides a more concise API compared to Fetch.
- Axios has built-in support for request and response interceptors.
- Display data from an API in your components
Once you’ve fetched the data, you can display it in your components. Let’s expand on the previous example to show more details about each user:
import React, { useState, useEffect } from "react";import axios from "axios";
function UserList() { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null);
useEffect(() => { axios .get("https://jsonplaceholder.typicode.com/users") .then((response) => { setUsers(response.data); setLoading(false); }) .catch((error) => { setError(error.message); setLoading(false); }); }, []);
if (loading) return <div>Loading...</div>; if (error) return <div>Error: {error}</div>;
return ( <div> <h1>User List</h1> {users.map((user) => ( <UserCard key={user.id} user={user} /> ))} </div> );}
function UserCard({ user }) { return ( <div style={{ border: "1px solid #ddd", margin: "10px", padding: "10px" }}> <h2>{user.name}</h2> <p>Email: {user.email}</p> <p>Phone: {user.phone}</p> <p>Website: {user.website}</p> <h3>Address:</h3> <p> {user.address.street}, {user.address.suite} </p> <p> {user.address.city}, {user.address.zipcode} </p> </div> );}
export default UserList;
Key points for displaying data:
- We’ve created a separate
UserCard
component to display individual user details. - We pass the user data as a prop to the
UserCard
component. - We use object destructuring in the
UserCard
component to easily access user properties. - We handle nested data (like the address) by accessing its properties directly.
Additional considerations:
-
Error Boundaries: You might want to implement React Error Boundaries to catch and handle errors gracefully.
-
Loading Skeletons: Instead of just showing “Loading…”, you could implement loading skeletons to improve user experience.
-
Pagination: If the API returns a large dataset, consider implementing pagination or infinite scrolling.
-
Caching: For frequently accessed data that doesn’t change often, you might want to implement caching to reduce API calls.
-
Custom Hooks: You could create a custom hook for data fetching to reuse the logic across different components:
import { useState, useEffect } from "react";import axios from "axios";
function useApi(url) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null);
useEffect(() => { axios .get(url) .then((response) => { setData(response.data); setLoading(false); }) .catch((error) => { setError(error.message); setLoading(false); }); }, [url]);
return { data, loading, error };}
// Usage in a componentfunction UserList() { const { data: users, loading, error, } = useApi("https://jsonplaceholder.typicode.com/users");
// Render component using users, loading, and error...}
This approach of fetching data from an API and displaying it in React components allows you to create dynamic, data-driven applications. Remember to handle loading and error states appropriately to ensure a good user experience.