20200530のReactに関する記事は6件です。

firebase login ができない時の対処法

概要

ReactをFirebaseにHostingしようとした際にハマったのでメモ

状況

yarn create react-app my-app

して

yarn add firebase-tools

して

firebase login

ちなみにこの後に聞かれるY/nはどっちでもいいです。

エラー

Firebase_CLI.png

何度やってもログインできない、、、。

対処法

調べたらこれをするといいらしい。

firebase login --no-localhost

これでもできない場合はsslの検証をパスする以下の環境変数を設定します。

export NODE_TLS_REJECT_UNAUTHORIZED=0
firebase login

Firebase_CLI-2.png
Woohoo!

解決

firebase init

:fire::fire::fire::fire:

? What do you want to use as your public directory? (public) //buildにします
yarn build
firebase deploy

で公開完了。

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

ReactアプリをFirebase Hostingにデプロイ

先日、初めてFirebaseを使ってデプロイする機会がありました。
基本的には案内に沿って進めるだけでしたが、せっかくなので手順をメモしておきます。

前提

  • デプロイするReactアプリがすでにある
  • yarnが使える環境である

また、自分はDocker環境を使っていたので、Docker環境でデプロイするにあたっての補足も一部書いています。

Firebase側

新規登録・プロジェクト作成

  1. Firebaseへアクセス

  2. 「使ってみる」「プロジェクトを作成」を選択
    Firebase トップ画面

  3. プロジェクトの作成

    • 1 - プロジェクト名を入力 + 利用規約にチェック して「続行」 Firebaseプロジェクト プロジェクト名入力画面
    • 2 - Google Analyticsを有効にして「続行」(※今回は有効にしていますが任意です) Firebaseプロジェクト Google Analytics設定画面
    • 3 - 連携するGoogle Analyticsアカウントを選択(もしくは新規作成)して「プロジェクトを作成」 Firebaseプロジェクト Google Analytics連携設定画面

少し時間がかかりますが、これでプロジェクトが作成されます。

アプリを追加

  1. プロジェクトトップから、追加するアプリのプラットフォームの中から「ウェブ」を選択
    Firebaseプロジェクト トップ画面

  2. ウェブアプリにFirebaseを追加

    • 1 - アプリのニックネームを入力 + Firebase Hosting設定を有効化 して「アプリを登録」 Firebaseアプリ追加 基本設定画面
    • 2 - Firebase SDKを予約済みURLから使用する場合は、スクリプトを控えておき「次へ」(※予約済みURLについてはこちらも参照) Firebaseアプリ追加 SDKスクリプト案内画面
    • 3 - Firebase CLIのインストール方法を確認して「次へ」 Firebaseアプリ追加 CLIインストール案内画面
    • 4 - Firebase Hostingへのデプロイ方法を確認して「コンソールに進む」 Firebaseアプリ追加 デプロイ案内画面

これでFirebaseプロジェクトにウェブアプリが追加されました。

Reactアプリ側

基本的には、Firebaseプロジェクトにアプリを追加した時に表示された手順で進めていきます。

Firebase SDKの導入

Firebase SDKを導入する方法としては

  • 予約済みURLにあるものを読み込み使用する
  • CDNで配信されているものを読み込み使用する
  • ライブラリとしてインストールし使用する

の3つのやり方があり、Firebase SDK Snippetに関しては Firebaseプロジェクトの「設定」「プロジェクトを設定」のマイアプリから確認できます。

補足として、予約済みURLというのはFirebase HostingでのURLのことを指します。そのURL配下にSDKおよびアプリの識別情報のファイルが配置されるようになっており、それを読み込んでSDKを使用する形になります。
そのため、この方法はFirebase Hostingを使ってホスティングする場合のみ、使用可能です。
主に同じコードを複数のFirebase Hostingにデプロイする際に便利な方法のようです。

自分も最初は予約済みURLでの方法にしていましたが、$ yarn startでの通常のローカルサーバからはSDKを読み込むことができないために、Warningが出るのが気になりやめました。

今回はライブラリとしてインストールして使用する方法で進めます。

ライブラリのインストール

$ yarn add firebase

.envを作成

設定値はFirebase SDK Snippetの「構成」から確認できます。
Firebase SDK Snippet 構成情報画面

.env
# Firebase
REACT_APP_APP_KEY=※apikey
REACT_APP_AUTH_DOMAIN=※authDomain
REACT_APP_DATABASE_URL=※databaseURL
REACT_APP_PROJECT_ID=※projectId
REACT_APP_STORAGEBUCKET=※storageBucket
REACT_APP_MESSAGING_SENDER_ID=※messagingSenderId
REACT_APP_APP_ID=※appId
REACT_APP_MEASUREMENT_ID=※measurementId

Firebase SDKの初期化を行うファイルを作成

各種Firebaseの機能を使うには最初に初期化処理を行う必要があります。
そのため、初期化処理をするファイルをあらかじめ用意しておき、機能を使うときにimportするようにします。

libs/Firebase.js
import firebase from 'firebase/app';
import 'firebase/analytics';

const config = {
  apiKey: process.env.REACT_APP_APP_KEY,
  authDomain: process.env.REACT_APP_AUTH_DOMAIN,
  databaseURL: process.env.REACT_APP_DATABASE_URL,
  projectId: process.env.REACT_APP_PROJECT_ID,
  storageBucket: process.env.REACT_APP_STORAGEBUCKET,
  messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID,
  appId: process.env.REACT_APP_APP_ID,
  measurementId: process.env.REACT_APP_MEASUREMENT_ID,
};

firebase.initializeApp(config);

export default firebase;

Google Analyticsにデータ送信する設定を追記

自分の場合はindex.jsに追記しました。
最初は、SDK組み込みだけで自動的にデータ送信してくれるものと思っていましたが、firebase.analytics()をやらないといけないようです。

以下の内容をReactDOM.renderの上に追記。

index.js
import firebase from './libs/Firebase';

if (process.env.NODE_ENV === 'production') {
  firebase.analytics();
}
.
.
.

Firebaseプロジェクトのアプリとの連携

Firebase CLIの導入

$ yarn global add firebase-tools

Dockerの場合では、Node.jsコンテナ起動時のコマンドでインストールするようにしました。

これでfirebaseコマンドが使えるようになります。

firebaseへログイン

Dockerの場合は、OAuth認証で9005ポートを使用するので事前に開けておきます。

$ firebase login
Firebase optionally collects CLI usage and error reporting information to help improve our products. Data is collected in accordance with Google's privacy policy (https://policies.google.com/privacy) and is not used to identify you.

? Allow Firebase to collect CLI usage and error reporting information? (Y/n)

Firebaseはオプションで、CLIの使用状況とエラー報告情報を収集して、製品の改善に役立てます。データはGoogleのプライバシーポリシー( https://policies.google.com/privacy )に従って収集され、ユーザーの特定には使用されません。

FirebaseがCLIの使用状況とエラー報告情報を収集することを許可しますか? (はい/いいえ)

任意で回答。

To change your data collection preference at any time, run `firebase logout` and log in again.

データ収集の設定をいつでも変更するには、 firebase logoutを実行して、再度ログインします。

Visit this URL on this device to log in:
https://accounts.google.com/o/oauth2/auth?XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Waiting for authentication...

認証のためのURLが表示されるので、ブラウザでアクセス。
内容を確認して「許可」
Firebase Googleアカウント認証確認画面

✔  Success! Logged in as XXX@gmail.com

無事に認証できるとCLI側はこの表示が出ます。
また、ブラウザ側では以下のような表示が出ます。
Firebase認証完了画面

連携・初期化処理

$ firebase init
? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices. (Press <space> to select, <a> to toggle all, <i> to invert selection)
❯◯ Database: Deploy Firebase Realtime Database Rules
 ◯ Firestore: Deploy rules and create indexes for Firestore
 ◯ Functions: Configure and deploy Cloud Functions
 ◯ Hosting: Configure and deploy Firebase Hosting sites
 ◯ Storage: Deploy Cloud Storage security rules
 ◯ Emulators: Set up local emulators for Firebase features   

このフォルダに設定するFirebase CLI機能はどれですか?スペースを押して機能を選択し、Enterを押して選択を確認します。 (スペース を押して選択、a を押してすべてを切り替え、i を押して選択を反転します)

今回はHostingのみ選択。

First, let's associate this project directory with a Firebase project.
You can create multiple project aliases by running firebase use --add,
but for now we'll just set up a default project.

? Please select an option: (Use arrow keys)
❯ Use an existing project
  Create a new project
  Add Firebase to an existing Google Cloud Platform project
  Don't set up a default project

まず、このプロジェクトディレクトリをFirebaseプロジェクトに関連付けます。
複数のプロジェクトエイリアスを作成するには、firebase use --add、
ただし、ここではデフォルトのプロジェクトを設定します。

今回はすでにFirebaseプロジェクトを作っているのでUse an existing projectを選択。

? Select a default Firebase project for this directory: (Use arrow keys)
❯ project-name (project-name)

このディレクトリのデフォルトのFirebaseプロジェクトを選択:(矢印キーを使用)

連携させるプロジェクトを選択。

Your public directory is the folder (relative to your project directory) that
will contain Hosting assets to be uploaded with firebase deploy. If you
have a build process for your assets, use your build's output directory.

? What do you want to use as your public directory? (public)

パブリックディレクトリは、プロジェクトディレクトリを基準にしたフォルダです。
firebase deployでアップロードされるホスティングアセットが含まれます。もし、あなたが
アセットのビルドプロセスがある場合は、ビルドの出力ディレクトリを使用します。

$ yarn buildでの生成物は/buildに作成されるので、buildと入力。

? Configure as a single-page app (rewrite all urls to /index.html)? (y/N)

SPAアプリとして構成しますか(すべてのURLを/index.htmlに書き換えます)? (はい/いいえ)

今回はSPAなのでyを入力。

✔  Wrote build/index.html

i  Writing configuration info to firebase.json...
i  Writing project information to .firebaserc...

✔  Firebase initialization complete!

これで設定ファイルが作成されて、連携は完了です。

Firebase Hostingへデプロイ

ビルドして、その生成物をデプロイします。

$ yarn build

$ firebase deploy
=== Deploying to 'project-name'...

i  deploying hosting
i  hosting[project-name]: beginning deploy...
i  hosting[project-name]: found 19 files in build
✔  hosting[project-name]: file upload complete
i  hosting[project-name]: finalizing version...
✔  hosting[project-name]: version finalized
i  hosting[project-name]: releasing new version...
✔  hosting[project-name]: release complete

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/project-name/overview
Hosting URL: https://project-name.web.app

表示されるホスティングURLにアクセスして、アプリの内容がちゃんと表示されれば、無事デプロイ完了です。


Firebaseを初めて使いましたが、思っていた以上に簡単にデプロイ出来てよかったです。
Reactとの相性もいいみたいですし、他の機能も使っていきたいなーと思います。
可能性が広がりますね!

いずれはデプロイフローをCIで自動化するつもりなので、自動化できたら追記するかもしれません。

参考リンクまとめ

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

React 基本のき

トランスコンパイラ

babelがいい感じに変換してくれてる

https://babeljs.io/repl#?browsers=defaults%2C%20not%20ie%2011%2C%20not%20ie_mob%2011&build=&builtIns=false&spec=false&loose=false&code_lz=DwEwlgbgfAEgpgGwQewAQHdkCcEmAenGiA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=true&presets=env%2Creact%2Cstage-2%2Cenv&prettier=false&targets=&version=7.10.1&externalPlugins=

webpack

https://webpack.js.org/

使われいる

<script src="/static/js/bundle.js"></script>

Component

クラスコンポーネント

import React, { Component } from "react";

class App extends Component {
  render() {
    return (
      <React.Fragment>
        <label htmlFor="bar">bar</label>
        <input
          type="text"
          onInput={() => {
            console.log("I am clicked");
          }}
        />
      </React.Fragment>
    );
  }
}

関数コンポーネント

import React from "react";

const App = () => {
  return (
    <React.Fragment>
      <Cat />
      <Cat />
      <Cat />
      <Cat />
    </React.Fragment>
  );
};

const Cat = () => {
  return <div>Coco</div>;
};
import React from "react";

function App() {
  return (
    <React.Fragment>
      <label htmlFor="bar">bar</label>
      <input
        type="text"
        onInput={() => {
          console.log("I am clicked");
        }}
      />
    </React.Fragment>
  );
}

props

  • componentの属性のこと
  • あるデータの属性に参照できるもののこと
const App = () => {
  const profiles = [
    { name: "Coco", age: 20 },
    { name: "Heck", age: 22 },
    { name: "NoName" }
  ];

  return (
    <React.Fragment>
      {profiles.map((profile, index) => {
        return <User key={index} name={profile.name} age={profile.age} />;
      })}
    </React.Fragment>
  );
};

// ここで受け取ってるprops
const User = props => {
  return (
    <div>
      Hi, I am {props.name}, and {props.age} years old
    </div>
  );
};

// 初期値設定できる
User.defaultProps = {
  age: 1
};

export default App;

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

【React】関数コンポーネントの引数に分割代入を使う

はじめに

参加したReactの勉強会で出てきた分割代入について調べてみた。

分割代入とは

ES2015から追加された構文でドキュメント(MDN)に書いてある説明はこんな感じ。

分割代入 (Destructuring assignment) 構文は、配列から値を取り出して、あるいはオブジェクトからプロパティを取り出して別個の変数に代入することを可能にする JavaScript の式です。

Reactで使ってみる

親コンポーネントから子コンポーネントにpropsでテキストを渡して表示するだけの適当なコードで動作確認してみた。

App.jsx
import React from "react";
import Text from "./Text";
import "./styles.css";

const App = () => {
  const text1 = "hogehoge";
  const text2 = "fugafuga";

  return (
    <div className="App">
      <Text text1={text1} text2={text2} />
    </div>
  );
};

export default App;

1.引数にpropsを渡す

個人的には一番最初に勉強したやり方。
Reactの公式ドキュメントにも同様の書き方が紹介されている。

この関数は、データの入った “props”(「プロパティ」の意味)というオブジェクトを引数としてひとつ受け取り、React 要素を返すので、有効な React コンポーネントです。

Text.jsx
import React from "react";

const Text = props => {
  return (
    <div>
      <p>{props.text1}</p>
      <p>{props.text2}</p>
    </div>
  );
};

export default Text;

propsがオブジェクトかどうか確認。

console.log(props);
// Object {text1: "hogehoge", text2: "fugafuga"}

2.引数にpropsを渡す&関数内で分割代入

分割代入を使うことでprops.text1のような冗長な書き方をしなくて良くなる。
サンプルコードは短いのでそうでもないが、コード量が増えるといちいちprops.を書くのがめんどい。

Text.jsx
import React from "react";

const Text = props => {
  // 分割代入
  const { text1, text2 } = props;

  return (
    <div>
      <p>{text1}</p>
      <p>{text2}</p>
    </div>
  );
};

export default Text;

const { text1, text2 } = props;の部分は下記コードと同じことをしている。
text1というimutableな変数が定義され、そこにprops.text1が代入されるイメージ。
const { text2, text1 } = props;のように順番を逆さにしてもOK。

const text1 = props.text1;
const text2 = props.text2;

3.引数に分割代入を使う

引数に分割代入を使うことでさらにコードを短く書くことができる。
propsで書くよりも、引数が明示的になるためコードの見通しが良くなる。

Text.jsx
import React from "react";

const Text = ({ text1, text2 }) => {
  return (
    <div>
      <p>{text1}</p>
      <p>{text2}</p>
    </div>
  );
};

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

reactでアニメーションを実装する

最近の勉強で学んだ事を、ノート代わりにまとめていきます。
主に自分の学習の流れを振り返りで残す形なので色々、省いてます。
Webエンジニアの諸先輩方からアドバイスやご指摘を頂けたらありがたいです!

アニメーションの実装

gifファイルの場合、実装は簡単だが容量が大きくなることも

import animation from "images/animation.gif";
・
・
<image src={animation} alt="トップ画像" />

Lottieで実装する!

Lottieとは?

Lottieという動画をアプリに組み込むためのライブラリを使うといいよ
JSONファイルを組込むので格段に軽くなる
必要なものをAirbnbがほとんど用意してくれててすごい?

以下の手順でJSONを書き出した後に実装していく!

1.ZXPInstallerをDL:http://aescripts.com/learn/zxp-installer/
2.BodymovinをDL(Aeのプラグイン):https://github.com/airbnb/lottie-web/
3.アプリに組み込みたい動画をAeで作成
4.動画をBodymovinでJSONで書き出し
5.プレビューでエラーがないか確認
6.問題なければ実装(orデータの受け渡し?)

実装の際はLottieをインストールし

$ npm i react-lottie

これでOK!

import React, { Component } from 'react'
import Lottie from 'react-lottie'
import animationData from '../lotties/4203-take-a-selfie.json'

class UncontrolledLottie extends Component {


  render(){

    const defaultOptions = {
      loop: true,
      autoplay: true,
      animationData: animationData,
      rendererSettings: {
        preserveAspectRatio: 'xMidYMid slice'
      }
    };

    return(
      <div>
        <h1>Lottie</h1>
        <p>Base animation free from external manipulation</p>
        <Lottie options={defaultOptions}
              height={400}
              width={400}
        />
      </div>
    )
  }
}

export default UncontrolledLottie

細かいオプションはLottieのドキュメントで確認できる!

参考資料

Lottie
How To Add Animations to React Apps with React-Lottie

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

【React】 useStateで配列を保存するときの注意点

useStateで配列を保存する時は、
新しい配列を生成して保存しないと再描画されません。

サンプルコード

×: 再描画されない

const [value, setValue] = React.useState(null)

value.push(props.newValue)

setValue(value) 

○: 再描画される

const [value, setValue] = React.useState(null)

setValue({...value, props.newValue})

理由

Reactではstateの値が変化した時にコンポーネントが再描画されます。

stateの値の変化を、Object.is() で判定しているとのことです。なので、pushspliceでは前回と同じ値と判定されるそうです。

そのため、再描画が起きないので、{...array, props.newValue} などで値をコピーした新しいオブジェクトを生成してstateに保存すると再描画されます。

参考

おまけ

新しい配列を生成する以外にも、immutable.jsというのを使っても解決できるそうです。

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