Lädt...


🔧 Mastering Data Fetching in React: A Journey from useEffect to Server Components


Nachrichtenbereich: 🔧 Programmierung
🔗 Quelle: dev.to

In modern web development, efficient data fetching is paramount to building responsive and user-friendly applications. This journey explores the evolution of data fetching techniques in React, starting with the foundational useEffect hook and progressing through to the advanced capabilities of React Query and React Server Components (RSC). Each method addresses specific needs, from simple API calls to complex data management and server-side rendering, enhancing performance and user experience. This guide provides a comprehensive understanding and practical examples of mastering data fetching in React, ensuring your applications remain robust and efficient.

useEffect Hook

The useEffect hook is one of the most commonly used hooks in React for handling side effects, like data fetching. When
you must fetch data from an API and display it in your component, useEffect is a go-to solution. It allows you to run
your code after the component renders, making it perfect for fetching data when it loads.

With useEffect, you define your data-fetching logic inside the hook, which runs after the component has rendered. This
approach is straightforward and works well for simple use cases. However, managing multiple API calls, handling caching,
and dealing with complex loading states can become cumbersome as your application grows. The useEffect hook provides a
lot of flexibility. Still, it requires you to handle most state management and side-effect control.

In the example below, we're building a simple AdminDashboard component that fetches a list of users, some analytics
data, and the latest notifications. To achieve this,
we use useEffect to trigger our data fetching logic
as soon as
the component mounts.

Here's how it works:

import React, { useEffect, useState } from 'react';
import axios from 'axios';

const AdminDashboard = () => {
    const [users, setUsers] = useState([]);
    const [analytics, setAnalytics] = useState({});
    const [notifications, setNotifications] = useState([]);

    useEffect(() => {
// Fetch User List
        const fetchUsers = async () => {
            try {
                const response = await axios.get('/api/users');
                setUsers(response.data);
            } catch (error) {
                console.error('Error fetching users:', error);
            }
        };

        // Fetch Analytics Data
        const fetchAnalytics = async () => {
            try {
                const response = await axios.get('/api/analytics');
                setAnalytics(response.data);
            } catch (error) {
                console.error('Error fetching analytics:', error);
            }
        };

        // Fetch Last Notifications
        const fetchNotifications = async () => {
            try {
                const response = await axios.get('/api/notifications');
                setNotifications(response.data);
            } catch (error) {
                console.error('Error fetching notifications:', error);
            }
        };

        fetchUsers();
        fetchAnalytics();
        fetchNotifications();
    }, []);

    return (
        <div className="admin-dashboard">
            <h1>Admin Dashboard</h1>

            <section>
                <h2>User List</h2>
                <ul>
                    {users.map(user => (
                        <li key={user.id}>{user.name}</li>
                    ))}
                </ul>
            </section>

            <section>
                <h2>Analytics</h2>
                <div>
                    <p>Total Users: {analytics.totalUsers}</p>
                    <p>Total Sales: {analytics.totalSales}</p>
                    {/* Add more analytics data as needed */}
                </div>
            </section>

            <section>
                <h2>Last Notifications</h2>
                <ul>
                    {notifications.map(notification => (
                        <li key={notification.id}>{notification.message}</li>
                    ))}
                </ul>
            </section>
        </div>
    );
};

export default AdminDashboard;

In this example, we use three separate functions within useEffect to fetch different sets of data: users, analytics,
and notifications. We make these API calls using Axios and store the results in state variables
like users, analytics, and notifications. The data is then rendered in corresponding sections of our dashboard.

React Query

While useEffect gets the job done for basic data fetching, when your app starts growing, and you need more advanced
features like caching, automatic refetching, and background updates, React Query is a game-changer. React Query is like
a supercharged data-fetching tool that simplifies the process and boosts performance and user experience.

With React Query, you can effortlessly manage data fetching, caching, background updates, and synchronization. It
handles loading and error states out of the box. Its caching mechanism ensures that your application is performant and
responsive. React Query is particularly useful in scenarios where you have complex data dependencies, need real-time
updates, or want to reduce the load on your server by reusing cached data.

Instead of relying on useEffect, React Query introduces hooks like useQuery and useQueries that simplify data
fetching and allow you to focus more on building your UI than managing API calls.

Let's take our previous AdminDashboard component, where we fetched users, analytics, and notifications
using useEffect and refactor it using React Query. Here's how it looks after the transformation:

import React from 'react';
import { useQueries } from 'react-query';
import axios from 'axios';

const fetchUsers = async () => {
    const response = await axios.get('/api/users');
    return response.data;
};

const fetchAnalytics = async () => {
    const response = await axios.get('/api/analytics');
    return response.data;
};

const fetchNotifications = async () => {
    const response = await axios.get('/api/notifications');
    return response.data;
};

const AdminDashboard = () => {
    const queryResults = useQueries([
        {
            queryKey: 'users',
            queryFn: fetchUsers,
        },
        {
            queryKey: 'analytics',
            queryFn: fetchAnalytics,
        },
        {
            queryKey: 'notifications',
            queryFn: fetchNotifications,
        }
    ]);

    const [usersQuery, analyticsQuery, notificationsQuery] = queryResults;

    if (usersQuery.isLoading || analyticsQuery.isLoading || notificationsQuery.isLoading) {
        return <div>Loading...</div>;
    }

    if (usersQuery.isError || analyticsQuery.isError || notificationsQuery.isError) {
        return <div>Error loading data</div>;
    }

    const users = usersQuery.data;
    const analytics = analyticsQuery.data;
    const notifications = notificationsQuery.data;

    return (
        <div className="admin-dashboard">
            <h1>Admin Dashboard</h1>

            <section>
                <h2>User List</h2>
                <ul>
                    {users.map(user => (
                        <li key={user.id}>{user.name}</li>
                    ))}
                </ul>
            </section>

            <section>
                <h2>Analytics</h2>
                <div>
                    <p>Total Users: {analytics.totalUsers}</p>
                    <p>Total Sales: {analytics.totalSales}</p>
                    {/* Add more analytics data as needed */}
                </div>
            </section>

            <section>
                <h2>Last Notifications</h2>
                <ul>
                    {notifications.map(notification => (
                        <li key={notification.id}>{notification.message}</li>
                    ))}
                </ul>
            </section>
        </div>
    );
};

export default AdminDashboard;

We swapped out useEffect for React Query's useQueries hook in this refactor. This change lets us fetch all three
data sets (users, analytics, and notifications) simultaneously and handle the results much cleaner. Each query is
defined with a queryKey (used by React Query for caching and tracking) and a queryFn, just our async function making
the API call.

React Server Components (RSC)

React Server Components (RSC)
are a newer addition to the React ecosystem. They bring a whole new approach to data
fetching by moving much of the heavy lifting to the server. Unlike traditional React components that run entirely on the
client, Server Components allow you to fetch data, render the component, and send the fully rendered HTML to the
client—all from the server. This means less JavaScript on the client, faster load times, and a smoother user experience.

RSC shifts the burden of data fetching to the server, reducing the amount of JavaScript sent to the client and improving
performance, especially on slower devices or networks. This approach is particularly beneficial for SEO and initial load
times, as the content is server-rendered and immediately available to users and search engines.

Let's refactor our AdminDashboard component, previously using React Query, into a Server Component. Here's what the
code looks like after the transformation:

import React from 'react';
import axios from 'axios';

// Fetch data on the server
const fetchUsers = async () => {
    const response = await axios.get('/api/users');
    return response.data;
};

const fetchAnalytics = async () => {
    const response = await axios.get('/api/analytics');
    return response.data;
};

const fetchNotifications = async () => {
    const response = await axios.get('/api/notifications');
    return response.data;
};

const AdminDashboard = async () => {
    const [users, analytics, notifications] = await Promise.all([
        fetchUsers(),
        fetchAnalytics(),
        fetchNotifications()
    ]);

    return (
        <div className="admin-dashboard">
            <h1>Admin Dashboard</h1>

            <section>
                <h2>User List</h2>
                <ul>
                    {users.map(user => (
                        <li key={user.id}>{user.name}</li>
                    ))}
                </ul>
            </section>

            <section>
                <h2>Analytics</h2>
                <div>
                    <p>Total Users: {analytics.totalUsers}</p>
                    <p>Total Sales: {analytics.totalSales}</p>
                    {/* Add more analytics data as needed */}
                </div>
            </section>

            <section>
                <h2>Last Notifications</h2>
                <ul>
                    {notifications.map(notification => (
                        <li key={notification.id}>{notification.message}</li>
                    ))}
                </ul>
            </section>
        </div>
    );
};

export default AdminDashboard;

We've moved all our data fetching to the server in this refactor. When AdminDashboard is requested, it runs the data
fetching logic for users, analytics, and notifications on the server using axios. The component waits for all the data
to be fetched with Promise.all, ensuring everything is ready before it starts rendering. Once the data is fetched, the
server renders the HTML and sends it directly to the client.

...

🔧 Mastering Data Fetching in React: A Journey from useEffect to Server Components


📈 70.4 Punkte
🔧 Programmierung

🔧 Using useEffect for Fetching Data in React


📈 42.45 Punkte
🔧 Programmierung

🔧 React Basics~useEffect/ Data Fetching~


📈 42.45 Punkte
🔧 Programmierung

🔧 Why is the useEffect hook used in fetching data in React?


📈 42.45 Punkte
🔧 Programmierung

🔧 Mastering React Functional Components: Hooks, useEffect, and Lifecycle Explained


📈 40.09 Punkte
🔧 Programmierung

🔧 Exploring “Data Fetching with React Server Components” with Next.js


📈 37.53 Punkte
🔧 Programmierung

🔧 UseEffect Vs. UseLayoutEffect: Why UseEffect Is a better Choice?


📈 34.51 Punkte
🔧 Programmierung

🔧 Mastering React Suspense for Data Fetching: A Complete Guide


📈 32.85 Punkte
🔧 Programmierung

🔧 Mastering TanStack Query: A Comprehensive Guide to Efficient Data Fetching in React


📈 32.85 Punkte
🔧 Programmierung

🔧 🔄 Class Components vs Functional Components: A Lifecycle Journey in React 🔄


📈 32.59 Punkte
🔧 Programmierung

🔧 Understanding useEffect: Enhancing Functional Components in React


📈 32.43 Punkte
🔧 Programmierung

🔧 Mastering Compound Components: Building Flexible and Reusable React Components


📈 32.29 Punkte
🔧 Programmierung

🔧 From useEffect to React Query: Modernizing your data management in react


📈 31.47 Punkte
🔧 Programmierung

🔧 React Query (TanStack Query): Efficient Data Fetching and State Management for React


📈 30.92 Punkte
🔧 Programmierung

🔧 Simplifying Data Fetching in React with Axios and React Query in Next.js


📈 30.92 Punkte
🔧 Programmierung

🔧 Mastering React Hooks 🪝: Dive into `useState`, `useEffect`, and Beyond!


📈 30.64 Punkte
🔧 Programmierung

🔧 Mastering React Hooks: useState and useEffect


📈 30.64 Punkte
🔧 Programmierung

🔧 Mastering React Hooks: A Deep Dive into useState and useEffect (Part 1 of 3)


📈 30.64 Punkte
🔧 Programmierung

🔧 Mastering React's `useEffect` Hook


📈 30.64 Punkte
🔧 Programmierung

🔧 Creating a CRUD Application with React: Mastering useState and useEffect


📈 30.64 Punkte
🔧 Programmierung

🔧 Typescript for React Components (or How To Write Components in React The Right Way)


📈 30.36 Punkte
🔧 Programmierung

🔧 Mastering React Server Components and Server Actions: A Comprehensive Guide


📈 28.62 Punkte
🔧 Programmierung

🔧 🛠️ React Server Components vs. Client Components: When to Use Which? ⚡


📈 27.52 Punkte
🔧 Programmierung

🔧 How to use React Server Components components on Storybook 8


📈 27.52 Punkte
🔧 Programmierung

🔧 Unleash the Power of SWR: Mastering Data Fetching in Next.js


📈 27.12 Punkte
🔧 Programmierung

🔧 Mastering Data Fetching in Vue.js: Using Axios and Vuex for State Management


📈 27.12 Punkte
🔧 Programmierung

🔧 Mastering API Requests in JavaScript: A 2024 Guide to Fetching Data


📈 27.12 Punkte
🔧 Programmierung

🔧 Different Ways to Fetch Data from APIs Using `useEffect` in React


📈 25.74 Punkte
🔧 Programmierung

🔧 Preventing Data Leaks in React.js: A Deep Dive into useEffect


📈 25.74 Punkte
🔧 Programmierung

🔧 Implement React v18 from Scratch Using WASM and Rust - [25] Suspense(2) - Data Fetching with use hook


📈 25.19 Punkte
🔧 Programmierung

🔧 React Suspense for data fetching


📈 25.19 Punkte
🔧 Programmierung

🔧 React Data Fetching Made Easy: SWR to the Rescue 🚨


📈 25.19 Punkte
🔧 Programmierung

matomo