20190727のReactに関する記事は8件です。

TypeScript x create-react-app x re-ducksのサンプル完成

概要

以下の記事のサンプルを一旦完成させた。
https://qiita.com/Miracle-T-Shirt09/items/c903e3460be6aa187426

前回投稿時からの変更点

主な変更点は以下の通り

  • TypeScriptの型推論を利用して不要な型指定は削除した
  • ducksディレクトリを廃止して階層を一つ浅くした
  • redux-actions-typeを利用してaction周りの型を整理
  • types.tsの廃止
  • mapDispatchToPropsは関数ではなくオブジェクトに

詳しくはこちら
https://github.com/MasahikoJinno/re-ducks-study/pull/6

修正点色々あるけど、方針的にはTypeScriptの型推論を生かして行こうよというもの。
ガチガチに型指定をしてしまったら記述量も増えてしまうので、TypeScriptの良いところに乗っかろうと思った。

今後の予定

今のままだと機能が少なすぎて明らかにTypeScriptもre-ducksもいらないので、以下のような機能をこのサンプルに盛り込むつもり。

  • Firebaseの利用
    • Firebase Authを使ったユーザ認証(多分Twitter認証)
    • FireStoreを使ったデータの永続化
  • ルーティングの実装
  • Service Workerの実装
    • 全く使ってないので
    • create-react-appでworkboxどう使うかもイマイチわからないから勉強がてら実装してみる
  • Next.jsの利用
    • もうcreate-react-appじゃなくなっちゃうけど
    • react-routerちょっとしんどいなって思ってきたのでNextのお勉強する

おわり

最後までご覧いただきありがとうございました。
質問等あれば受け付けます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【個人開発/OSS】カンバンアプリを作ってみた

TL;DR

  • 非同期処理の返り値をStateの初期値にしたい時は、useEffectを使う
  • Skebanをよろしくおねがいします

はじめに

Skeban v0.1.0を先日リリースしました。
個人利用のみに対象を絞ったElectron製カンバンアプリです。


アプリ名は、Sketches your brain in kanbanから命名しました。
決してあのスケバンではありません。
Webp.net-resizeimage.png

動作サンプル

skeban.gif

使いみち

一般的なカンバンの使い方であるTodo管理や、ちょっとした情報の整理にどうぞ。

作った理由

なんとなくアカウント不要のカンバンが欲しかったからです。
どうせ作るならMITライセンスのOSSにしようと思い、OSSとなりました。

インストール方法

Windows

インストーラーをダウンロードしてインストールしたら完了です。

Mac

Mac版に関しては、私がMacを持っていないためインストーラーを生成出来ませんでした。
ですので、以下のコマンドでGithubからソースをクローンしてパッケージ化を行ってインストーラーを作成してください。

git clone https://github.com/roottool/Skeban.git
yarn install
yarn run build
yarn run pack:mac

技術スタック

  • Electron
  • React
  • unstated-next
  • react-beautiful-dnd
  • TypeScript
  • indexedDB
  • webpack
  • babel

今回はcreate-react-appを使わず、webpackとbabelの設定を自分で行いました。
理由は、今までwebpackとbabelの設定を行ったことがなかったので経験値を積むためです。
しかし、create-react-appのお手軽感を改めて実感することになりました…。
D&D実装は、react-beautiful-dndを使用しました。

unstated-next

unstated-nextは、Reduxのようなアプリ全体での状態管理を行うことが出来るパッケージです。
Reduxと違う点は、Reactに実装されているReact Hooksのみで書けることです。
今回のアプリ作成に限って言えば、ReduxではおなじみのReducerDispachActionを書いていません。
React HooksのuseStateで作成した状態更新関数だけでアプリを作成出来ました。

indexedDB

indexedDBは、ブラウザに搭載されているDBです。
ラッパーのDexie.jsを使用しました。

苦労ポイント

DBからのレコード取得が非同期であるため、useStateの引数にasync関数を作って返り値にDBからの取得結果を初期値としていました。
ですが、PromiseとuseStateで設定していた取得結果の配列型との型不一致エラーとなってしまいました。
そこで、状態のマウント時とアップデート時に実行されるuseEffectで解決しました。
これは。useEffectをUpdateタイミングのみで使いたいというstackoverflowの回答を利用しています。
マウント時のタイミングで、DBからのレコード配列をuseStateで作成した状態更新関数で状態更新を行いました。

最後に

localStorageを使ってみたり個々のコンポーネントのStateだけで作れないかと色々模索していましたが、今の形に落ち着きました。
Skebanをよろしくおねがいします。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

windows react再立ち上げ 備忘録(完全自分用)

1 フォルダー内のアドレスバーにpowershellと打ち込む

2 powershell上に入力

1 cd 親フォルダー内に作ったフォルダー
2 npm start

3 ローカル環境が立ち上がる

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

React の useMemo と useCallback がよくわからなかったので調べたメモ

useCallback とは

https://ja.reactjs.org/docs/hooks-reference.html#usecallback

メモ化されたコールバックを返します。

useMemo とは

https://ja.reactjs.org/docs/hooks-reference.html#usememo

メモ化された値を返します。

わかるようなわかないような感じだったので挙動を確認するコードを書きました。

コード

import * as React from "react";
import { useCallback, useMemo, useState } from "react";

let tmpHandleClick: () => void;
let tmpHandleClick2: () => void;

export const Component: React.FC = () => {
  const [count, setCount] = useState(0);
  const double = useMemo(() => {
    console.log("double が計算された。");
    return count * 2;
  }, [count]);

  const handleClick = useCallback(() => {
    setCount(prev => prev + 1);
  }, []);
  if (tmpHandleClick !== handleClick) {
    console.log("handleClick が生成された。");
  }
  tmpHandleClick = handleClick;

  // ----------------------

  const [count2, setCount2] = useState(0);
  const dobule2Func = (i: number) => {
    console.log("double2 が計算された。");
    return i * 2;
  };
  const double2 = dobule2Func(count2);

  const handleClick2 = () => {
    setCount2(count2 + 1);
  };
  if (tmpHandleClick2 !== handleClick2) {
    console.log("handleClick2 が生成された。");
  }
  tmpHandleClick2 = handleClick2;

  return (
    <div>
      <p>state: {count}</p>
      <p>double: {double}</p>
      <button onClick={handleClick}>handleClick</button>
      <br />
      <p>state2: {count2}</p>
      <p>double2: {double2}</p>
      <button onClick={handleClick2}>handleClick2</button>
    </div>
  );
};

動かしてみた結果

初期表示時

スクリーンショット 2019-07-27 18.31.31.png

初回なのですべてのログが表示される。

handleClick 押下時

スクリーンショット 2019-07-27 18.32.41.png

handleClick は新たに生成されない。
handleClick は useCallbackの第2引数に空配列を与えているので初期表示時にのみ生成される。
useCallback は第2引数の配列に含まれる値に変化があった時のみ関数を新しく生成するため。

handleClick2 押下時

スクリーンショット 2019-07-27 18.33.01.png

useMemo の 第2引数に渡している count に変更がないため double は計算されない。

まとめ

react の component が render されると、毎回、component の中身がすべて再実行されるが、
useMemo, useCallback を使うと必要ない再計算、再生成が行われない。

という当たり前のことが実際に動かしたことで腹落ちしました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Gatsby.jsでサイトを構築したので良いところを書いていく

Gatsby.jsのすヽめ

静的サイトジェネレータは文字どおり静的サイトを生成してくれる技術です。

コードを書いてコンパイルすればいい感じにサイトを生成してくれるので、あとはそれを適当なサーバでホスティングするだけ。サーバーの環境構築もDBの世話も不要、というシンプルさが魅力です。

Markdownファイルからページを生成させればブログとしても使えるし、NetlifyCMSやStrapiのようなヘッドレスCMSと組み合わせればCMS付きのWEBサイトにもできます。

日本での普及度はまだまだですが、個人的にはWordPressにとって代わるポテンシャルを持った技術だと思っています。WPは定期的に面倒を見てあげないといけないうえ、カスタマイズしようとすると色々厄介ごとが多いイメージだったので、その辺の煩雑さから一挙におさらばできる静的サイトジェネレータはまさに救世主でした(WPみたいな定期的なアップデートが不要なのは本当嬉しい:sob:)。

で、数ある静的サイトジェネレータ中でもGatsby.jsは日本での知名度が高めなうえ、使ってみて良いものだったので、普及の一助になればと思い、感じた美点や個人的に苦労した点などを書いていきます。

導入する際の参考にどうぞ。

Gatsby.js公式はこちら
※静的サイトジェネレータ自体の持つメリットはすでにいくつも紹介している記事があるので省きます

良いところ

SPAを手軽に構築できる

Gatsby.jsはReact製のジェネレータ、ということで、面倒なこと一切なしでSPAとして動作してくれます。

SPAはインタラクティブなWEBアプリを構築する際に優れたUI/UXを提供できる一方で、普通のブログやWEBサイトに使うにはコストが高すぎるとも思います。ただ静的なコンテンツを返すだけのサイトをSPA化しても、そのために支払う開発コストに対して得られる効用が釣り合わないわけです。

が、構築に支払うコストの高さという問題さえ解消できてしまえば、すべてのWEBサイトをSPA化してしまっても良いくらい優れた技術なのもまた事実です。

Gatsby.jsはSPA構築のコスト問題を解決する優れた手段です。

なにせコマンドひとつで完璧に動作するReactアプリを構築できてしまうし、新しいページを追加する手段は/src/pages/以下のディレクトリにページ名を冠したJSファイルを追加するだけです。

凝ったことをやろうとしない限り、面倒なことはなにひとつ考える必要がありません。

充実したチュートリアルとドキュメント

Gatsby.jsはまだ日本語の情報は少ないものの、公式がかなりしっかりとしたstep by stepのチュートリアルを準備しています。

このチュートリアルはモダンなフロントエンド技術への入門書にもなっていて、進めるうちにReactやGraphQLなどの扱いが分かる他、surge.shLightHouseといった便利なサービスにも触れられるようになっています。

そのため、Gatsby.jsのチュートリアルを進めることは、初心者がReactやモダンなフロントエンド環境に慣れるための優れた選択肢でもあります(実際私がそうでした)。

ドキュメントも恐ろしく充実しており、開発する過程で生じたほとんどの疑問は公式サイトを読んでいれば解消できるはずです。ぜひ一度覗いてみて欲しいのですが本当に細かいところまで網羅されており、開発コミュニティの活発さと普及にかける熱意が伝わってきます。

もちろんドキュメントは英語ですが、基本的に平易な英文で書かれているため、英語が読めない人でもGoogle翻訳を通せば問題なく理解することができるはずです。

強力なGraphQL

GraphQL and Gatsby
Gatsby.jsはGraphQLを通じてあらゆるデータソースを呼び出し、サイト内に埋め込めるようになっています。サイトメタデータ、ディレクトリ内にある画像ファイルやマークダウンファイル、さらには外部ソースまで、あらゆるものをです。

これは実際に使ってみるとかなり強力で、私はひとつサイトを作り終える頃にはすっかりGraphQLの虜になってしまいました。この便利さを体験してしまうと、RESTAPIで何度もリクエストを飛ばすのがひどく煩雑に感じられるようになってしまうほどです。

まだ普及度の低いGraphQLのパワーを手軽に体感できるという点でもGatsby.jsはおすすめです。

モダンなフロントエンド環境が手軽に手に入る

基本的にGatsby.jsプロジェクトは、トランスパイラやコンパイラがすべて設定され、あとはコードを書くだけ、という状態で生成されます。そのため、あなたが環境構築のためにやることはほとんどありません。せいぜいプラグインを入れてconfigを編集するくらいです。
環境構築というのはいつの時代も面倒で手間のかかる作業です。その過程をほとんど自動でやってくれるというのは、フロントエンド初学者にとってはもちろん、すべての開発者にとって嬉しいところです。

高いカスタマイズ性

高機能なシステムはその完成度の高さ故に窮屈に感じられることがありますが、Gatsby.jsはそうではありません。

もし望むなら、あなたはすべてのコンポーネントを1から自分で作ることができるし、それらを自由に組み合わせてサイトを構築することができます。そのため、あり合わせのテーマやテンプレートを適用するだけでは満足できないとき、Gatsby.jsは良い選択肢となります。

もちろん、手早く見た目の整ったサイトを構築したければGatsby.jsに用意された豊富なスターターキットから好きなものを選ぶこともできるし、これらのスターターキットをベースにしてカスタマイズすることもできます。

静的サイトジェネレータとしては日本における普及度が高め

静的サイトジェネレータはまだ普及度の低い技術なのである程度は英語圏の情報を漁る覚悟は必要ですが、Gatsby.jsは日本語圏での情報が比較的多いです。このあたりも初学者にとって優しい点だと思います。

Reactコンポーネントを利用できる

React用に作られたコンポーネントは基本的にGatsby.jsでも利用することができます。

個人的に詰まったところ

以下のところは私個人の技術力不足による面が大きいので、JSやReactの仕様をちゃんと理解できていれば相対的に無視できるようになる問題です。が、使っていて苦労したところも一応書いておきます。

React製であるということ

これは享受できる恩恵の裏返しなのですが、サイトのあらゆる機能をReactの作法に則って実装する必要があるというのは留意しておくべきです。

ReactやJSXの独特のクセを理解する必要はあるし、素のHTML&CSS&JSでは簡単だった機能の実装に思わぬ手間がかかることもあります。もちろんReactに初めて触る場合、そこそこの学習コストを支払うことになります。

これは私個人の知識不足による面が大きいのですが、Gatsby.jsは(というよりReactは)リッチなアニメーションの実装に苦労することが多かったように思います。基本的にReactはほとんどのJavaScriptライブラリを活用できますが、それらを導入するとき毎回「ReactとJSXの作法に則って実装するにはどうすれば良いか」を考えなければならないというのは、けっこう疲れるものです。

こういう事情もあり、私は基本的に外部のJSライブラリは使わずに、CSSアニメーションとJSによるイベント制御を組み合わせてアニメーションを実装しました(凝ったことをやろうとしない限りそれで十分)。

ともかく、Reactに対応していない/Reactにおける実装方法がはっきりしないJSライブラリなどを使いたい場合は苦労するかもしれないし、自身のスキルレベルによってはライブラリの採用自体を断念することになるかもしれません。

複雑なアニメーションやUIを実装しようとするとそれなりの技術力が必要

上の項目と通じる話ですが、シェーダーなどを使ったリッチなグラフィック表現を実装したい時詰まることがありました(まあこれは素のHTML+CSS+JSで実装しても難易度が高いものですが)。

個人的な体感では、ReactはHTML&CSS&JSでアニメーションをやるくらいなら問題なく実装できました(Reactの作法でイベントを制御する必要がある程度)が、ここにWebGLを加えてさらにリッチな表現を、となると私個人の技術力ではちょっと手に負えなくなる印象でした。
私はWebGLやGLSLシェーダーに関してほぼ素人なので、チュートリアルを見よう見まねで実装することはできても、それをReact上で応用することができなかったのです。

ReactからWebGLを扱いたい場合、react-three-fibergl-reagtといったものがあるため、やってできないことはないはずです。が、現状の自分のスキルでこれらを扱うにはちょっと荷が重かったようです。

逆に、WebGLの扱いに習熟していたり、シェーダー自分で書けるよ、というレベル人ならこの辺も何の問題もないかと思います。
私もそれくらいのレベルになったらまた挑戦するつもりです:muscle::muscle:

元来、シェーダーによるリッチな表現は画面遷移の発生しないSPAとの相性が良いはずなんですよね。

おわり

そういうわけで、個人的な感想を交えたGatsby.jsの紹介でした。
総じて、いまWordPressが占めているような需要にはほとんどの場合応えられる技術であるように思います。

Webサイトやブログを構築したい方、モダンなフロントエンド環境に触れたい方、手軽にSPAを手に入れたい方、WordPressのかわりになる技術を探している方、一度試してみては如何でしょう。上にも書きましたが日本での普及度が比較的高めなのもあり、静的サイトジェネレータは迷ったらとりあえずこれやっとけば良いのでは、とすら思います。

ReactやGraphQLが入ってくる都合上若干学習コストは高めかと思いますが、得られる恩恵は間違いなく大きいです。シンプルなのにパワフルで良い技術ですよ。

環境構築手順はこちらからどうぞ?チュートリアルのpart0

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

入門React redux ~reduxの概念は繰り返し使ってなれよう~

Reduxとは

Reactでのフロントアプリケーション開発の際にセットで扱われることの多いのがこのreduxです。

A predictable state container for Javascript apps.
公式サイトより。

以下の4つを特徴としています。

・予測可能
・中央化
・デバックがしやすい
・柔軟性のある

なぜこれを使う必要があるのか

あるコンポーネントで定義した値を別のコンポーネンントでも使いたいという場合に、ReactではPropsというものを使って親コンポーネントから子コンポーネントへと値を渡します。必ずこの方向になっていて、単方向データフローはReactの三代特徴のうちの1つです。

しかし、孫やさらに別の複数のコンポーネントで値を使いたいといった場合に、バケツリレーで渡していくのはしんどいということでこのReduxというものを使ってコンポーネント全体で値を管理できる仕組みが作られました。

【Reduxのアーキテクチャー】

redux_archtecture.png

これによってデータが単方向になることが保証され、状態の変更が追いやすく破綻しにくいシステムを作ることができます。

Reduxの構成要素

redux公式のサンプルを元にreduxの構成要素の概要について説明します。

state

コンポーネントの状態を表す値を保管するためのものです。コンポーネントの「現在の状態」を扱うためのものです。コンポーネントの表示を変えたりするためにstateを更新します。

公式では stateとして数値リテラルの0が直接reducerに渡されています。

export default (state = 0, action) => {

Reducer

Actionとstateを受け取って、新しいStateを返します。

※語源は化学の Reduce(還元)です

CuO + H2 → Cu + H2O
export default (state = 0, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1
    case 'DECREMENT':
      return state - 1
    default:
      return state
  }
}

https://github.com/reduxjs/redux/blob/master/examples/counter/src/reducers/index.js#L1

store

state(データ)を保管し管理するもの。

const store = createStore(counter)

https://github.com/reduxjs/redux/blob/master/examples/counter/src/index.js#L7

action

actionとは 実態はJavascriptのオブジェクト
actionは必ずtypeというメンバを必ず持ちます。

{type: 'DECREMENT'}
{type: 'INCREMENT'}

https://github.com/reduxjs/redux/blob/master/examples/counter/src/index.js#L13

dispatch

dispatchがreducerを呼び出して、よびだされたreducerにより値が操作されます。

onIncrement={() => store.dispatch({ type: 'INCREMENT' })}
onDecrement={() => store.dispatch({ type: 'DECREMENT' })}

まとめ

Reducer、action、 storeなど複数の新しい概念が登場するためはじめは理解するのが簡単ではないと思いますが、繰り返しコードを読んだり実際に書いたりしてならしていきましょう。

参考

https://redux.js.org/
https://github.com/reduxjs/redux/tree/master/examples/counter

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Firebase+React+TypeScriptの開発環境を作成しよう

準備

Firebaseの管理コンソールに従って、firebase deployができる状態になるまでまずはもっていきましょう。
Hostingで公開するのにローカルで編集するローカルディスク上のディレクトリーが仮にpublicだとした場合、publicをいったん消しましょう。

$ rm -rf public

テンプレートアプリを作成

$ npx create-react-app public --typescript

firebase.jsonを編集

public/buildディレクトリーをFirebaseに公開するので、public/buildにします。

{
  "firestore": {
    "rules": "firestore.rules",
    "indexes": "firestore.indexes.json"
  },
  "hosting": {
    "public": "public/build",
    "ignore": [
      "firebase.json",
      "**/package-lock.json",
      "**/public/**",
      "**/package.json",
      "**/README.md",
      "**/yarn.lock",
      "**/src/**",
      "**/.*",
      "**/node_modules/**"
    ]
  },
  "storage": {
    "rules": "storage.rules"
  }
}

(余談)複数のサイトを運用するときは、"hosting"エントリーの値を配列にする

{
  "firestore": {
    "rules": "firestore.rules",
    "indexes": "firestore.indexes.json"
  },
  "hosting": [{
    "site": "foo",
    "public": "foo/build",
    "ignore": [
      〜
    ]
  },
  {
    "site": "bar",
    "public": "bar/build",
    "ignore": [
      〜
    ]
  }],
  "storage": {
    "rules": "storage.rules"
  }
}

まずは動作確認

次のコマンドを実行しましょう。

$ cd public
$ npm start

自動的にWebブラウザーが開いて以下の画面が表示されたら成功です。
スクリーンショット 2019-07-27 1.27.23.png

ただし、これだけではReactとTypeScriptの開発環境ができただけです。
まだFirebaseの機能は使用できません。

Firebaseパッケージをインストール

Webに公開するWebアプリなので、Firebaseの公式ドキュメントの通りにscriptタグで読み込ませたいところですが、せっかくnpmでパッケージをインストールできるので、npmを使ってインストールしましょう。
こうした方が管理しやすいですしね。

$ npm i --save firebase firebase-tools

FirestoreとCloud Storage for Firebaseのセキュリティルールを修正

APIキーを公開するので、FirestoreとClouse Storage for Firebaseのセキュリティールールが甘いと費用がかさんだり、無料枠を使い切ってアカウントがロックされるといったことが起こりかねません。
ログインしてなくては使用できない設定に変更しましょう。

後で匿名ログインを有効にするのでログイン状態になると考えていてください。

firestore.rules
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth.uid != null;
    }
  }
}
storage.rules
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth.uid != null;
    }
  }
}

Firebaseへの接続設定を書き込む

不要なimportや、機能は適宜取り除いてください。

public/src/firebase.tsx
import * as firebase from "firebase/app";
import "firebase/auth";
import "firebase/firestore";
import "firebase/functions";
import "firebase/messaging";
import "firebase/storage";
import "firebase/performance";

const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_AUTH_DOMAIN",
  databaseURL: "https://YOUR_DATABASE_URL",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
  appId: "YOUR_APP_ID"
};

firebase.initializeApp(firebaseConfig);

firebase.performance();
firebase.auth().signInAnonymously();

export default firebase;

firebaseConfigは、Firebaseの管理コンソールから取得します。

スクリーンショット 2019-07-27 1.55.31.png

赤枠の部分をコピペしましょう。

firebase.tsxをインポートする

App.tsxなど、Firebaseに接続するソースに以下のimport分を追加すると使えるようになります。

import firebase from './firebase';

例えば、FirestoreのSDKを使いたければつぎのようにします。

const db = firebase.firestore();

Firebaseで匿名ユーザーを有効にする

スクリーンショット 2019-07-27 2.06.07.png

開発業務を行う

firebase serveコマンドで確認したいところかもしれませんが、それだとTypeScriptがコンパイルされなかったり、Reactが動作しないので、npm startコマンドを実行してください。

$ npm start

ブラウザーが開いて、Reactの画面を表示します。JavaScriptのコンソールにエラーが表示されていなければ匿名ログインができていると判断してください。

プログラムソースを編集したらブラウザには即座に変更が反映されますので開発がしやすいですね。

Firebaseにデプロイする

Firebaseいデプロイするには、npmでビルドしてからデプロイします。

$ cd public
$ npm rub build
$ cd ..
$ firebase deploy

firebase deployの終わりの方にURLが表示されるので、そのURLにアクセスしてデプロイを確認してみてください。

終わりに

かなり端折りましたが、基本的にはこれで開発を進められると思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Firebase Hosting+React+TypeScriptの開発環境を作成しよう

準備

Firebaseの管理コンソールに従って、firebase deployができる状態になるまでまずはもっていきましょう。
Hostingで公開するのにローカルで編集するローカルディスク上のディレクトリーが仮にpublicだとした場合、publicをいったん消しましょう。

$ rm -rf public

テンプレートアプリを作成

$ npx create-react-app public --typescript

firebase.jsonを編集

public/buildディレクトリーをFirebaseに公開するので、public/buildにします。

{
  "firestore": {
    "rules": "firestore.rules",
    "indexes": "firestore.indexes.json"
  },
  "hosting": {
    "public": "public/build",
    "ignore": [
      "firebase.json",
      "**/package-lock.json",
      "**/public/**",
      "**/package.json",
      "**/README.md",
      "**/yarn.lock",
      "**/src/**",
      "**/.*",
      "**/node_modules/**"
    ]
  },
  "storage": {
    "rules": "storage.rules"
  }
}

(余談)複数のサイトを運用するときは、"hosting"エントリーの値を配列にする

{
  "firestore": {
    "rules": "firestore.rules",
    "indexes": "firestore.indexes.json"
  },
  "hosting": [{
    "site": "foo",
    "public": "foo/build",
    "ignore": [
      〜
    ]
  },
  {
    "site": "bar",
    "public": "bar/build",
    "ignore": [
      〜
    ]
  }],
  "storage": {
    "rules": "storage.rules"
  }
}

まずは動作確認

次のコマンドを実行しましょう。

$ cd public
$ npm start

自動的にWebブラウザーが開いて以下の画面が表示されたら成功です。
スクリーンショット 2019-07-27 1.27.23.png

ただし、これだけではReactとTypeScriptの開発環境ができただけです。
まだFirebaseの機能は使用できません。

Firebaseパッケージをインストール

Webに公開するWebアプリなので、Firebaseの公式ドキュメントの通りにscriptタグで読み込ませたいところですが、せっかくnpmでパッケージをインストールできるので、npmを使ってインストールしましょう。
こうした方が管理しやすいですしね。

$ npm i --save firebase firebase-tools

FirestoreとCloud Storage for Firebaseのセキュリティルールを修正

APIキーを公開するので、FirestoreとClouse Storage for Firebaseのセキュリティールールが甘いと費用がかさんだり、無料枠を使い切ってアカウントがロックされるといったことが起こりかねません。
ログインしてなくては使用できない設定に変更しましょう。

後で匿名ログインを有効にするのでログイン状態になると考えていてください。

firestore.rules
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth.uid != null;
    }
  }
}
storage.rules
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth.uid != null;
    }
  }
}

Firebaseへの接続設定を書き込む

不要なimportや、機能は適宜取り除いてください。

public/src/firebase.tsx
import * as firebase from "firebase/app";
import "firebase/auth";
import "firebase/firestore";
import "firebase/functions";
import "firebase/messaging";
import "firebase/storage";
import "firebase/performance";

const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_AUTH_DOMAIN",
  databaseURL: "https://YOUR_DATABASE_URL",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
  appId: "YOUR_APP_ID"
};

firebase.initializeApp(firebaseConfig);

firebase.performance();
firebase.auth().signInAnonymously();

export default firebase;

firebaseConfigは、Firebaseの管理コンソールから取得します。

スクリーンショット 2019-07-27 1.55.31.png

赤枠の部分をコピペしましょう。

firebase.tsxをインポートする

App.tsxなど、Firebaseに接続するソースに以下のimport分を追加すると使えるようになります。

import firebase from './firebase';

例えば、FirestoreのSDKを使いたければつぎのようにします。

const db = firebase.firestore();

Firebaseで匿名ユーザーを有効にする

スクリーンショット 2019-07-27 2.06.07.png

開発業務を行う

firebase serveコマンドで確認したいところかもしれませんが、それだとTypeScriptがコンパイルされなかったり、Reactが動作しないので、npm startコマンドを実行してください。

$ npm start

ブラウザーが開いて、Reactの画面を表示します。JavaScriptのコンソールにエラーが表示されていなければ匿名ログインができていると判断してください。

プログラムソースを編集したらブラウザには即座に変更が反映されますので開発がしやすいですね。

Firebaseにデプロイする

Firebaseいデプロイするには、npmでビルドしてからデプロイします。

$ cd public
$ npm rub build
$ cd ..
$ firebase deploy

firebase deployの終わりの方にURLが表示されるので、そのURLにアクセスしてデプロイを確認してみてください。

終わりに

かなり端折りましたが、基本的にはこれで開発を進められると思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む