6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

React-Firebase-Hooks VS React-Query-Firebase

Last updated at Posted at 2022-02-12

初めに

業務システムの開発で firebase を使おうとなった時にfirebase SDKをそのまま使用したくないと思ったので (SDKにあまり依存させたくないという思い) 何かライブラリなどないかと調べたところ本記事タイトルのReact-Firebase-HooksReact-Query-Firebase を見つけたので両者の検証, 比較をしようと思います。

Firestoreからのデータ取得

Firestore Databaseからのデータ取得の実装コードです。

React-Firebase-Hooks

import { collection } from 'firebase/firestore';
import React from 'react';
import { useCollection } from 'react-firebase-hooks/firestore';

import { db } from '@/lib/firebase';

const ReactFirebaseHooksSample = () => {
  const [snapshot, isLoading, error] = useCollection(collection(db, 'users'), {
    snapshotListenOptions: { includeMetadataChanges: true },
  });

  return (
    <div>
      <p>
        {error && <strong>Error: {JSON.stringify(error)}</strong>}
        {isLoading && <span>Collection: Loading...</span>}
        {snapshot && (
          <span>
            Collection:{' '}
            {snapshot.docs.map((doc) => (
              <React.Fragment key={doc.id}>{JSON.stringify(doc.data())}, </React.Fragment>
            ))}
          </span>
        )}
      </p>
    </div>
  );
};

React-Query-Firebase

import { useFirestoreQuery } from '@react-query-firebase/firestore';
import { collection, query } from 'firebase/firestore';
import React from 'react';

import { db } from '@/lib/firebase';

const ReactFirebaseHooksSample = () => {
  const ref = query(collection(db, 'users'));
  const usersQuery = useFirestoreQuery(['users'], ref);
  const { data: snapshot, isLoading, error } = usersQuery;

  return (
    <div>
      <p>
        {error && <strong>Error: {JSON.stringify(error)}</strong>}
        {isLoading && <span>Collection: Loading...</span>}
        {snapshot && (
          <span>
            Collection:{' '}
            {snapshot.docs.map((doc) => (
              <React.Fragment key={doc.id}>{JSON.stringify(doc.data())}, </React.Fragment>
            ))}
          </span>
        )}
      </p>
    </div>
  );
};

Firebase Authを利用したログイン・ログアウト

Firestore Authenticationを利用した認証周りの実装コードです。

React-Firebase-Hooks

import { signInWithEmailAndPassword, signOut } from 'firebase/auth';
import React from 'react';
import { useAuthState } from 'react-firebase-hooks/auth';

import { auth } from '@/lib/firebase';

const login = async () => {
  await signInWithEmailAndPassword(auth, 'test@gmail.com', 'password');
};
const logout = async () => {
  await signOut(auth);
};

const ReactFirebaseHooksSample = () => {
  const [user, isLoading, error] = useAuthState(auth);

  return (
    <div>
      <p>
        {error && <strong>Error: {error}</strong>}
        {isLoading && <span>Collection: Loading...</span>}
      </p>
      {user && (
        <div>
          <p>Current User: {user.email}</p>
          <button onClick={logout}>Logout</button>
        </div>
      )}
      <button onClick={login}>Login</button>
    </div>
  );
};

React-Query-Firebase

import { useAuthUser } from '@react-query-firebase/auth';
import { signInWithEmailAndPassword, signOut } from 'firebase/auth';
import React from 'react';

import { auth } from '@/lib/firebase';

const login = async () => {
  await signInWithEmailAndPassword(auth, 'test@gmail.com', 'password');
};
const logout = async () => {
  await signOut(auth);
};

const ReactQueryFirebaseSample = () => {
  const { data: user, isLoading, error } = useAuthUser(['user'], auth);

  return (
    <div>
      <p>
        {error && <strong>Error: {error}</strong>}
        {isLoading && <span>Collection: Loading...</span>}
      </p>
      {user && (
        <div>
          <p>Current User: {user.email}</p>
          <button onClick={logout}>Logout</button>
        </div>
      )}
      <button onClick={login}>Login</button>
    </div>
  );
};

比較・考察

コード量, SDKへの依存度ともにほぼ等しいと言える結果になりました。
これらの結果からでは, 両者に大きな差はないためどちらを使っても変わらないと思われます。
しかし, React-Query-Firebaseについてみると, クエリを投げる関数の引数にクエリキーをしていることがわかります。ここで, 公式のREADMEから抜粋した一文について見てみます。

Data fetching is handled via Queries and Query Keys, meaning components can share > data throughout your application without needless database reads. (データの取得は、クエリとクエリキーで処理されます。つまり、コンポーネントは、不必要なデータベース読み取りをすることなく、アプリケーション全体でデータを共有することができます。)

このようにReact-Query-Firebaseでは必要なデータのみに焦点を絞ってデータを取得するので, パフォーマンス向上を狙えるのではないかなと思います。

感想

ここまで読んでくださった方は結局どっちが良いのかと思われるかもしれませんが, 個人的にはReact-Query-Firebaseに軍配が上がるのではないかと思います。
理由としては, 上記で挙げたパフォーマンスの観点以外にも, 以下のような強みがあります。

  • React-Query-FirebaseはReact Query上に構築されているため, React Queryの旨味も持っている
  • ユーザーのサインイン、ドキュメントの削除、トランザクションの実行、イベントの記録などの処理をMutationを介して行うことで複雑なローカルローディングやエラーステートの管理などに手間をとられずにアプリケーションに集中することができる。

もう一方のReact-Firebase-Hooksについては, 記述量が少なくなるという点以外に強みが見当たリませんでした。(気付いてないだけかもしれませんが)

参考

https://github.com/CSFrequency/react-firebase-hooks/tree/v4.0.2
https://github.com/invertase/react-query-firebase
https://react-query-firebase.invertase.dev/

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?