Billboard Ads

5 Advanced Data-Fetching Techniques in React for Enhanced User Experience

Source: Medium

Data fetching is a critical yet challenging aspect of modern application development. The unpredictable nature of network conditions — slow connections, system errors, downtimes — along with the inherent complexity of asynchronous programming can significantly impact the functionality and reliability of your application. Moreover, inefficient data fetching strategies can lead to performance bottlenecks, prolong loading times, and detract from user experience.

In this article, I’ll delve into five data fetching patterns that can optimize your React application’s performance and enhance user experience. If you would like some in-depth material and practical examples on this topic, have a look at my free tutorial here: Advanced Data-Fetching Patterns in React. This tutorial is designed to complement the concepts we’ll discuss here and provide you with a hands-on learning experience.

I have also published it as a book. If you prefer to read it in PDF or EPUB, you can grab a copy on leanpub.

Introduction to Parallel Data Requests

Parallel data requests involve fetching multiple data sources simultaneously rather than sequentially. This technique is particularly beneficial when your application needs to retrieve data from independent sources or APIs, and none of these requests depend on the results of the others. By executing these requests in parallel, you can significantly reduce the overall loading time of your application.

Think of we have a page below. The user About section and Friends section need to fetch data separately on /users/<id>and /users/<id>/friends. If we fetch data in each component itself, it will cause the request waterfall issue.

const Profile = ({ id }: { id: string }) => {
  const [user, setUser] = useState<User | undefined>();

  useEffect(() => {
    const fetchUser = async () => {
        const data = await get<User>(`/users/${id}`);
        setUser(data);
    };
    fetchUser();
  }, [id]);

  return (
    <>
      {user && <About user={user} />}
      <Friends id={id} />
    </>
  );
};

Above we fetch data for the basic user information, and in Friends:

const Friends = ({ id }: { id: string }) => {
  const [users, setUsers] = useState<User[]>([]);

  useEffect(() => {
    const fetchFriends = async () => {
        const data = await get<User[]>(`/users/${id}/friends`);
        setUsers(data);
    };
    fetchFriends();
  }, [id]);

  return (
    <div>
      <h2>Friends</h2>
      <div>
        {users.map((user) => (
            <Friend key={user.id} user={user} />
        ))}
      </div>
    </div>
  );
};

We could simply modify the code to request data all together in Profile:

const Profile = ({ id }: { id: string }) => {
  const [user, setUser] = useState<User | undefined>();
  const [friends, setFriends] = useState<User[]>([]);

  useEffect(() => {
    const fetchUserAndFriends = async () => {
        const [user, friends] = await Promise.all([
          get<User>(`/users/${id}`),
          get<User[]>(`/users/${id}/friends`),
        ]);
        setUser(user);
        setFriends(friends);
    };
    fetchUserAndFriends();
  }, [id]);

  return (
    <>
      {user && <About user={user} />}
      <Friends users={friends} />
    </>
  );
};

Use parallel data requests in scenarios where your application requires data from multiple endpoints that aren’t interdependent. This is common in dashboards, complex forms, or pages that display aggregated data from various sources. Implementing parallel requests ensures that the user doesn’t have to wait unnecessarily for sequential network calls to complete, thus enhancing the responsiveness and efficiency of your app.

Read Also
Post a Comment