Bookmark profile
React Query

React Native 애플리케이션을 개발할 때, 상태 관리와 데이터 fetching은 필수적인 작업이다. 하지만 이 두 가지 작업을 어떻게 효율적으로 처리할지 고민이 많을 수 밖에 없다.

이렇게 고민을 하며 인터넷을 찾아보면 다음 두개의 키워드가 주로 보인다. Container / React Query.

React Query와 Container Component는 상태 관리와 데이터 fetching을 위한 문제들을 해결하기 위한 강력한 도구들이다.

이번에는 이 강력한 도구들이 무엇이고, 어떻게 사용하는지 알아보려고 한다.

React Query

React Query는 서버 상태를 관리하는 강력한 라이브러리다.

이 라이브러리를 사용하면, 데이터 fetching, caching, synchronization, and background updates를 간편하게 처리할 수 있다. 즉, React Query의 가장 큰 장점은, 서버와의 데이터 통신을 효율적으로 처리할 수 있도록 도와주는 것이다.

  • 데이터 fetching: useQuery, useMutation 등의 훅을 사용하여 데이터를 fetching한다.
  • 자동 캐싱: 데이터를 자동으로 캐싱하고 네트워크 요청을 최소화한다.
  • 자동 갱신: 데이터를 주기적으로 백그라운드에서 갱신하여 최신 상태를 유지한다.
  • 오류 처리: 오류 상태를 쉽게 관리할 수 있는 기능을 제공한다.
// src/components/UserList.js
import React from 'react';
import { useQuery } from 'react-query';
import { fetchUsers } from '../api/users';

const UserList = () => {
  const { data, error, isLoading } = useQuery('users', fetchUsers);

  if (isLoading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <ul>
      {data.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
};

export default UserList;

React Query 와 다르게 전반적인 상태관리를 돕는 Container Component

Container Component는 애플리케이션의 상태 관리와 비즈니스 로직을 처리하는 컴포넌트이다.

이 컴포넌트는 데이터를 fetching하고, 상태를 관리하며, 비즈니스 로직을 실행하여 데이터를 Presentational Component에 전달하는 역할을 한다.

주요 기능

  • 상태 관리: Redux, Context API, MobX 등을 사용하여 전역 상태를 관리한다.
  • API 호출: 서버와의 통신을 통해 데이터를 fetching하고 상태를 업데이트한다.
  • 비즈니스 로직: 데이터 변환, 필터링, 정렬 등의 로직을 처리한다.
// src/containers/UserContainer.js
import React, { useEffect } from 'react';
import { connect } from 'react-redux';
import { fetchUsers } from '../store/actions/userActions';
import UserList from '../components/UserList';

const UserContainer = ({ users, fetchUsers, loading, error }) => {
  useEffect(() => {
    fetchUsers();
  }, [fetchUsers]);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error: {error}</p>;

  return <UserList users={users} />;
};

const mapStateToProps = (state) => ({
  users: state.users.data,
  loading: state.users.loading,
  error: state.users.error,
});

const mapDispatchToProps = {
  fetchUsers,
};

export default connect(mapStateToProps, mapDispatchToProps)(UserContainer);

두 개를 함께 사용하는 방법: 최고의 조합 만들기

Container Component와 React Query는 각각의 장점을 살려 애플리케이션의 상태 관리와 데이터 fetching을 효율적으로 처리할 수 있는 도구이다. Container Component는 상태 관리와 비즈니스 로직을 처리하고, React Query는 서버 상태를 간편하게 관리할 수 있게 해준다.

이 두 가지를 함께 사용하면 코드의 가독성과 유지보수성을 높이고, 효율적으로 상태와 데이터를 관리할 수 있다.

// src/containers/UserContainer.js
import React from 'react';
import { useQuery } from 'react-query';
import { fetchUsers } from '../api/users';
import UserList from '../components/UserList';

const UserContainer = () => {
  const { data, error, isLoading } = useQuery('users', fetchUsers);

  if (isLoading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return <UserList users={data} />;
};

export default UserContainer;

그런데… firestore의 onSnapshot과 react query는 역할이 겹치는거 아닌가? 라는 생각이 들었다.

실제로도 그랬다.

firestore의 onSnapshot과 react query는 공존할 수 있는 걸까?

두개의 역할은 겹치지만, 장단점이 있다. firestore의 onSnapshot은 실시간 데이터 처리에 유용하고, react query는 복잡한 서버의 상태 관리에 유용하다고 한다.

하지만, 여러개의 기기들 사이에서 실시간 데이터 동기화가 필요한 경우에는 onSnapshot을 사용해야만 한다. 둘 다 하려면 코드가 매우 비효율적으로 변하게 된다.

나는 모바일 기기 및 태블릿에서 실시간 동기화가 가능한 onSnapshot을 쓸거다.