Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
29
Help us understand the problem. What is going on with this article?
@daishi

react-firebase-hooksを使ってみた(Firestore Hooks編)

More than 1 year has passed since last update.

はじめに

前回の記事でreact-firebase-hooksのAuth Hooksを使ってみたのですが、今回はFirestore Hooksに挑戦したいと思います。

react-firebase-hooks

リポジトリはこちらです。

このライブラリは、4種類のAPIを提供しています。

  • Auth Hooks
  • Cloud Firestore Hooks
  • Cloud Storage Hooks
  • Realtime Database Hooks

今回対象とするのは2つ目のFirestore Hooksです。

テストデータの作成

最初に、Firestoreのコンソールでコレクションといくつかのドキュメントを作成します。コレクション名はtodosとしました。

image.png

コーディング

モジュールのimport

今回使うモジュールをimportします。

import React, { useState } from "react";
import ReactDOM from "react-dom";

import firebase from "firebase";
import { useCollectionData } from "react-firebase-hooks/firestore";

TodoListコンポーネント

todosコレクションを表示するコンポーネントを作ります。

const TodoList = () => {
  const [values, loading, error] = useCollectionData(
    firebase.firestore().collection("todos"),
    { idField: "id" }
  );
  if (loading) {
    return <div>Loading...</div>;
  }
  if (error) {
    return <div>{`Error: ${error.message}`}</div>;
  }
  return (
    <ul>
      {values.map(value => (
        <li key={value.id}>{value.title}</li>
      ))}
    </ul>
  );
};

idFieldでidを取得するところがポイントです。

NewTodoコンポーネント

todosコレクションに新たなドキュメントを追加するためのコンポーネントを作ります。

const NewTodo = () => {
  const [title, setTitle] = useState("");
  const [pending, setPending] = useState(false);
  const add = async () => {
    setTitle("");
    setPending(true);
    try {
      await firebase
        .firestore()
        .collection("todos")
        .add({ title });
    } finally {
      setPending(false);
    }
  };
  return (
    <div>
      <input value={title} onChange={e => setTitle(e.target.value)} />
      <button type="button" onClick={add}>
        Add
      </button>
      {pending && "Pending..."}
    </div>
  );
};

エラー処理は省略しています。

Appコンポーネント

最後に、全体をつなげるAppコンポーネントとReactDOMのrenderです。

const App = () => {
  return (
    <div>
      <TodoList />
      <NewTodo />
    </div>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

CodeSandbox

完成したものがこちらです、実際に動作させるためにはforkしてfirebaseConfigを置き換える必要がありますのでご注意ください。

image.png

おわりに

Firestoreのリアルタイム更新とReact Hooksはとても相性がいいと感じました。ドキュメントを追加したら、すぐに更新されます。Firestoreのコンソールから追加しても同様です。

今回は、useCollectionDataを使いましたが、用意されているhooksはさらにあります。

  • useCollection
  • useCollectionOnce
  • useCollectionData
  • useCollectionDataOnce
  • useDocument
  • useDocumentOnce
  • useDocumentData
  • useDocumentDataOnce

Once系は一度だけの取得なのですが、その場合はhookがどれだけ役立つかは微妙です。callbackから使うことになることが多い気がします。また、Data系のhookはTypeScriptの型が付けられますが、ソースコード上は単にアサーションしているだけなので、予期せぬランタイムエラーが発生する可能性がありそうです。結局、独自の拡張をしようと思うとcustom hooksを作ることになりそうですが、その先に本ライブラリのhooksから合成できるかはやってみないと分からないといった感じになりそうです。

29
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
daishi
React開発者向けオンラインサロン「React Fan」はこちらから→ https://react-fan.axlight.com https://twitter.com/reactfanjp
informetis
電力分野でイノベーションを目指す技術集団です。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
29
Help us understand the problem. What is going on with this article?