- 投稿日:2020-10-17T19:13:48+09:00
firebaseでpull request ごとにpreviewをdeployするgithub action
概要
firebaseで、spaをnetlify やvercel のようにプルリクごとにURLを変えてdeployしたい。
how to
firebaseの初期化
公式
firebase toolをグローバルにinstall
今回はdeployする directoryはdistをしていします。(firebaseのdefaultはpublic)npm i -g firebase-tools firebase login firebase hosting #deloyするdirectoryをdist にするchannel deployコマンドをpackage.jsonに追加
previewようのdeployはchannel deployというコマンド使います。
そのため、以下のように scriptに追加します。{ "name": "firebase deploy app", "version": "1.0.0", "private": true, "scripts": { "dev": "nuxt-ts", "build": "nuxt-ts build", "start": "nuxt-ts start", "generate": "nuxt-ts generate", "lint:js": "eslint --ext .js,.vue --ignore-path .gitignore .", "lint:style": "stylelint **/*.{vue,css} --ignore-path .gitignore", "lint": "yarn lint:js && yarn lint:style", "test": "jest", "channel-deploy": "firebase hosting:channel:deploy" ←# 追加 },github workflowを設定する
以下のように設定します。
firebase-deploy.ymlname: CI on: [push] jobs: FrontDeploy: name: FrontDeploy runs-on: ubuntu-latest steps: - name: Checkout Repo uses: actions/checkout@main - name: setup Node uses: actions/setup-node@v1 with: node-version: '12' registry-url: 'https://registry.npmjs.org' - name: Install Dependencies run: yarn - name: Build run: yarn build - name: deploy to Firebase Hosting shell: bash run: yarn channel-deploy $(echo ${GITHUB_REF#refs/heads/}) --token=${{ secrets.FIREBASE_TOKEN }}こちらでは、branch名を取得しています。
$(echo ${GITHUB_REF#refs/heads/})tokenを取得
以下コマンドで、tokenを取得できます
firebase login:ci取得したtokenを
FIREBASE_TOKEN
にいれましょう。以上でdeployできるはずです!
twitterもフォローよろしくおねがいします。 !
- 投稿日:2020-10-17T15:46:14+09:00
【React Native + Expo】React Hook Formでバリデーションを簡易実装してみる
React Hook Formはフォームバリデーションをシンプルかつ簡単に記述できる便利なライブラリです。
FormikやRedux Formなどバリデーションに関してのライブラリは他にもありますが、
パフォーマンスの良さや記述量の少なさからこちらのライブラリを使うと実装が楽になるのでオススメです。ReactNativeに関しては以下のURLにクイックスタートがかかれているので、参考にしてみてください。
https://react-hook-form.com/jp/get-started#ReactNativeReact Nativeの注意点
ReactNativeのサポートはしっかりとされていますので、使うことはできます。
ただし注意点としては、Reactと同様のAPIが使えない部分があるとのこと。React Native と互換性のない API がいくつかあります (Web とネイティブとの API の違い)。
また、書き方についても手動登録 (manual register)が必要とのこと。。。
とにかくソースコードを確認してみましょう。ソースコード
import { useForm, Controller } from 'react-hook-form';const { register, control, handleSubmit, errors } = useForm(); const onSubmit = (data) => console.log(data);<Controller control={control} render={({ onChange, onBlur, value }) => ( <TextInput onBlur={onBlur} onChangeText={value => onChange(value)} value={value} /> )} name="firstName" rules={{ required: "入力が必要です。" }} defaultValue="" /> {errors.firstName && <Text>{errors.firstName.message}</Text>}該当ソースコードは以上で、だいぶスッキリと書ける印象です。
補足
Controller
<Controller control={control} render={({ onChange, onBlur, value }) => ( <TextInput /> )} name="firstName" rules={{ required: "入力が必要です。" }} defaultValue="" />先程の「手動登録 (manual register)が必要」というのはController内にあるrulesにあたる箇所になります。
そもそも、registerとはバリデーションルールを設定するためのもので、useForm内でも定義することができます。errors
{errors.firstName && <Text>{errors.firstName.message}</Text>}バリデーションエラ-の内容はuseFormで定義されているerrorsを呼び出すことで確認できます。
上記のソースコードでのerrorの内容は、Controller内にあるrulesに定義した「入力が必要です。」が出力されます。実装例
— がーみ (@garmigarmi) October 17, 2020終わりに
今回紹介した内容は一部分だけですので、APIリファレンスを読んで書き換えたりすると理解が深まるかと思います。
また。実装で必要なバリデーションルールに沿ったものが、作れるのかを試してみようと思うので
詳細な作りに関してはまた別の記事で書こうかと思います。まだ、まとめきれていない部分が多々あるので、実装方法としてこうしたほうが良いとか間違いがあれば教えていただくと嬉しいです。
- 投稿日:2020-10-17T13:40:41+09:00
【React】 合成イベント(SyntheticEvent) を利用する時注意点
Reactの合成イベント(SyntheticEvent )特性
- ブラウザのイベントハンドラーとReactのSyntheticEvent は別である
- SyntheticEventはPullingされる。
- SyntheticEvent再使用される。
- 全ての属性は呼び出し後に初期化される。
実際にエラーを作てみましょう
export default function App() { const syntheticEvent = (event) => { // 1.全ての属性は呼び出し後に初期化される。 setTimeout(() => {. console.log(event.target.value); //2. 非同期でevent.target.valueを呼ぶと警告が発生する!! }, 1000); }; return ( <div className="App"> <input type="text" onChange={syntheticEvent} /> </div> ); }警告発生
Warning: This synthetic event is reused for performance reasons. If you're seeing this, you're accessing the property >
target
on a released/nullified synthetic event. This is set to null. If you must keep the original synthetic event >around, use event.persist(). See https://fb.me/react-event-pooling for more information.解決方法
1. event.persist()を追加する
export default function App() { const syntheticEvent = (event) => { event.persist() // 1. 警告が書いているメソッドを追加 setTimeout(() => { console.log(event.target.value); }, 1000); }; return ( <div className="App"> <input type="text" onChange={syntheticEvent} /> </div> ); }補足
非同期処理の中でイベントのプロパティにアクセスしたい場合は、event.persist() をイベント> 内で呼び出す必要があります。これにより、合成イベントがイベントプールの対象から除外され、イベントへの参照をコードで保持できるようになります。上のreactドキュメントはevent.persist()を利用する場合。
①. 合成イベントがイベントプールから除外される。
②. ①の理由で呼び出し後に初期化されない。
③. ②の理由で非同期の内部でもevet.target.valueの値が利用できるevent.persist()を利用する事は上の①の理由でオススメしない。
2. event.target.valueの値をPrimitive(プリミティブ)値で取得
export default function App() { const syntheticEvent = (event) => { const value = event.target.value // 1.primitive値で取得 setTimeout(() => { console.log(value); //2.警告は発生しない値を表示 }, 1000); }; return ( <div className="App"> <input type="text" onChange={syntheticEvent} /> </div> ); }この方法でする事をオススメします。
合成イヴェントを除外しなくても利用できます。結論
Reactの合成イベントを利用する時は非同期処理について注意が必要
setStateなども非同期で処理するので注意!参考記事
https://ja.reactjs.org/docs/events.html#gatsby-focus-wrapper
- 投稿日:2020-10-17T13:16:54+09:00
未経験がポートフォリオで使ったReactライブラリ(その3)
まえがき
業務でReactを触る機会が出てきそうなので、復習のため、以前作ったポートフォリオを個人的に振り返ります。
フロントエンド
https://github.com/momonoki1990/house_work_memo_front
バックエンド(Express)
https://github.com/momonoki1990/house_work_memo_backサービス
https://house-work-memo-front.herokuapp.com/
(Herokuのフリープランで定期モニタリングも解除したので、起動がめちゃ遅いです(1分くらい?))
(表示が変な場合は、バックエンドの起動に時間がかかっています。そのままお待ちいただくと表示されます)前回
未経験がポートフォリオで使ったReactライブラリ(その1)
https://qiita.com/momonoki1990/items/a1edd4fa922cd3ed3b14
未経験がポートフォリオで使ったReactライブラリ(その2)
https://qiita.com/momonoki1990/items/49f490378c724daaaf68React Router関連
react-router-dom connected-react-router @types/react-router-domreact-router-dom
SPAでは全てのアクセスはindex.htmlにリダイレクトされます。
その為、サーバーサイドではなくクライアントサイド(Webアプリ側)でルーティングできます。
2時間で作れる簡単フォーラムWebアプリ!
https://www.techpit.jp/courses/20/curriculums/21/sections/184/parts/663Reactでページを切り替える(「遷移」といっていいんだろうか..)ために使います。
react-routerとreact-router-domがあり、迷いましたが、結論
迷わずreact-router-domを使おう。
react-routerとreact-router-domの違い
https://qiita.com/koja1234/items/486f7396ed9c2568b235とのことで、react-router-domを使いました。
connected-react-router
SPA(Single Page Application)は、描画されるコンポーネントが変わって画面が遷移したように見えてもURLは変わっていません。
なので、ユーザーはブラウザの「戻るボタン」を押しても前の画面に戻れないのですね。
ページ遷移なしで画面がヌルッと切り替わることがSPAのメリットであると同時に、ブラウザの「戻るボタン」を使えないのはユーザービリティを下げかねないですよね。
そこでconnected-react-routerを使って、SPAだけどURLルーティングを実装します。
connected-react-routerでSPAの描画をURLで切り替える
https://tech.playground.style/javascript/connected-react-router/URLルーティングを実装するために使います。
文字だけで書いてるとわかりづらいですが、react-router-domだけだと、表示するページが変わっても、URLは変わらないし、「戻る」「進む」ボタンも使えないんですね。
connected-react-routerを使うと、react-routerによるルーティングの状態をReduxで管理できるようになります。
具体的には、表示されるページが切り替わるとURLが変わり、「戻る」「進む」ボタンが使えるようになります。Redux Logger
redux-logger @types/redux-loggerredux-loggerは数あるredux middlewareの中で一番知られているものではないでしょうか。
(中略)
ActionがDispatchされる前後のstateとDispatchされたActionをconsole上に出力します。
意図したActionが発動しているか、その前後で期待したstateの変更が意図した通りに行われているかどうか
確認するためにはとても有用です。
redux-loggerの導入とオススメのLog出力設定の紹介
https://qiita.com/tatapopo/items/3bdf2f3132948e3d75e3上で説明されているとおりですが、ActionをDispatchする(Reduxのstateを変更する)前後のstateの中身が見えるようになるので、便利です。
使うのも、基本的にReduxのStoreを作成する際に、applyMiddlewareに噛ませるだけなので、簡単です。あとがき
以上です。復習のためまとめてみましたが、いろんな方の記事の切り貼りになってしまいました。
でも、それでいいのか!