- 投稿日:2021-03-22T22:25:47+09:00
React+Reduxについて簡単に解説してみた
初めに(前書き)
最近では、Reactが3大Webフレームワーク(=Vue&React&Angular)の中で、抜きに出ているとのことですが、いかんせん、浅学非才の私には(一般的に用いられる)ReactとReduxを組み合わせたシステムの構成や全体の動作が把握しづらいです・・・(泣)。したがって、(勝手ながら)この記事は、ReactとReduxについて学び始めた(自分と同じ立場の)方を対象にしたいと思います。
本題(本文)
概説としては、ReactはWebアプリケーションのヴューを担当し、Reduxはモデルないしヴューモデルを担当します。※ちなみに、「ヴューモデル」とは、MVCに取って代わられるであろう「MVVM(Model-View-ViewModel)」と呼ばれるアーキテクチャーの構成要素です。
Reactでは、「コンポーネント」と呼ばれる単位でヴューを構成します。※ここでいう「ヴュー」とは、(大雑把にいえば)Webページのことです。
このコンポーネントは、jsファイル(やjsxファイル)に記述されます。このファイル内では、ヴューを構成する各コンポーネントに対応するrender関数内でタグ(やカスタムタグ)を書いて、これを呼び出し元にreturnします。こうすることで、実際のヴューが形作られて、描画されていきます。Reduxでは、前述のコンポーネントに「ステート」と呼ばれる特定の状態があって、ユーザーからの入力(=インタラクション)などによって起こるステートの変化を読み取って、これをヴューに反映させます。さらには、ステートに変更があった場合に、その変更を自動的に検知して、ヴューに対して、変更された内容の伝達および、更新の依頼をします。
従来のMVCアーキテクチャーでは、(通常は、)コントローラーがユーザーからの入力を受け付けて、モデル(≒ステートの集まり)(≒「Store」)の内容を参照し、その内容をヴューに伝達すると共に、ヴューに更新を依頼するという流れであり、これがMVC全体の仕組みでしたが、このヴューの更新を自動化することがMVVMの特徴であり、強味なのです。
終わりに(後書き)
ReactとReduxを組み合わせたシステムは、私の想像以上に複雑で、ここでは簡単に解説させていただきましたが、実際には、「Action」「ActionCreator」「Store」「Container」「Reducer」・・・などといった構成要素・概念が絡んでくるので、・・・(私の非力ゆえに)割愛させていただきました(笑)。また、あまりゴチャゴチャとした解説では、却って、わかりづらくなるかとも思いましたので・・・(言い訳)。
- 投稿日:2021-03-22T17:57:10+09:00
Vite+React+Typescriptでimportのパスを必要最低限にする
Viteを使用してReact+Typescriptのプロジェクトの開発をしています。
Typescriptのimportのパスに../のような相対パス指定を指定したくなくて、必要最低限の指定で利用できないものかと考えていました。
ほんのわずかなコードでも、コードが小さければ不具合はそれだけ減らせるからです。そこでtsconfig.jsonに
compilerOptions.baseUrlの設定をしたものの、Viteはその設定を読んでくれませんでした。
Viteにはvite.config.tsという設定ファイルがあるのでそこに設定をしなければならないようです。私のプロジェクトでは、アトミックデザインを採用しています。
tsconfig.jsonの例
baseUrlを書くと相対パスの指定がない場合にどこを起点にパスを解決するかを指定できます。
ここでは"src"としています。
pathsという設定もあるのですが、それもViteは読み込まないようです。{ "compilerOptions": { "target": "ESNext", "lib": ["DOM", "DOM.Iterable", "ESNext"], "types": ["vite/client"], "allowJs": false, "skipLibCheck": false, "esModuleInterop": false, "allowSyntheticDefaultImports": true, "strict": true, "forceConsistentCasingInFileNames": true, "module": "ESNext", "moduleResolution": "Node", "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react", "baseUrl": "src" }, "include": ["./src"] }vite.config.tsの例
tsconfig.jsonに書いたbaseUrlやpathsはViteは読んでくれません。
そこでvite.config.tsは以下のようにエイリアスを設定します。
import * as path from "path"の部分がエラーになる方は、yarn add @types/node -Dかnpm -i -D @types/nodeを実行してくださいimport { defineConfig } from "vite" import reactRefresh from "@vitejs/plugin-react-refresh" import * as path from "path" // https://vitejs.dev/config/ export default defineConfig({ plugins: [reactRefresh()], resolve: { alias: { "atoms": path.resolve(__dirname, "src/atoms"), "molecules": path.resolve(__dirname, "src/molecules"), "organisms": path.resolve(__dirname, "src/organisms"), "templates": path.resolve(__dirname, "src/templates"), "pages": path.resolve(__dirname, "src/pages") } } })import文はどうなる?
ディレクトリー構成は以下のようになっているとします。
: ├ pages │ ├ index.ts │ └ HomePage.tsx ├ templates │ ├ index.ts │ └ MainTemplate.tsx :index.tsは以下のようになっているとします。
import MainTemplate from "templates/MainTemplate" export { MainTemplate }import文は以下のように指定すれば、必要最低限の指定でコンポーネントを呼び出せます。
import * as React from "react" import { MainTemplate } from "templates" export default () => ( <MainTemplate> コンテンツ </MainTemplate> )注意
- 本プロジェクトで使用しているViteのバージョンは
2.1.2です。バージョン1系だと、vite.config.tsの書き方が違う可能性があるのでご注意ください。- 指定したエイリアス以外のディレクトリーが必要になったときは、vite.config.tsにメンテナンスが必要になりますが、そのようなことが起こることはあまりない前提です。
- 投稿日:2021-03-22T13:49:30+09:00
Amplify×Lambda×SESでメール配信
概要
開発中のアプリにレポートを投稿した際にメール通知が必要ということでAWSのSESを利用した検証を行いました。
メール通知やメール配信を考えている方の少しでも参考になればと思います。事前に
アプリケーション
Amplify SNS Wrokshopの「FOLLOW/TIMELINE機能の実装」までを実装済みの方を前提としています。
しかし、SESの実装自体は簡単ですので、Amplify SNS Wrokshopをやっていない方でも実装できると思います。Email認証
SESの送信元は検証済みのEメールアドレスが必要となります。
検証済みのEメールアドレスがない方はこちらを参考に準備してください。実装
権限設定
LambdaにSESの権限を与えるには
amplify/backend/function/createPostAndTimeline/createPostAndTimeline-cloudformation-template.jsonを編集します。
lambdaexecutionpolicy>PolicyDocument>Statement>Actionにses:SendEmailとses:SendRawEmailを追加します。"lambdaexecutionpolicy": { "DependsOn": [ "LambdaExecutionRole" ], "Type": "AWS::IAM::Policy", "Properties": { "PolicyName": "lambda-execution-policy", "Roles": [ { "Ref": "LambdaExecutionRole" } ], "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents", "ses:SendEmail", // Here! "ses:SendRawEmail" // Here! ], "Resource": { "Fn::Sub": [ "arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:*", { "region": { "Ref": "AWS::Region" }, "account": { "Ref": "AWS::AccountId" }, "lambda": { "Ref": "LambdaFunction" } } ] } } ] } } },AWS SDKのインストール
AWS SDKを
amplify/backend/function/createPostAndTimeline/srcにインストールします。cd amplify/backend/function/createPostAndTimeline npm install aws-sdk送信処理
ここから
amplify/backend/function/createPostAndTimeline/src/index.jsに送信処理を加えていきます。まずは、AWS SDKを読み込みます。
const AWS = require("aws-sdk")さらに、フォロー処理の下あたりに処理を加えます。
1.送信するEmailのparamsを設定
2.リージョンを設定
3.送信処理exports.handler = async (event, context, callback) => { ・ ・ ・ const listFollowRelationshipsResultWithOwner = await graphqlClient.query({ query: gql(listFollowRelationships), fetchPolicy: 'network-only', variables: queryInput, }); // 1.送信するEmailのparamsを設定 const params = { Destination: {// 必須 CcAddresses: [ 'EMAIL_ADDRESS', ], ToAddresses: [ 'EMAIL_ADDRESS', ] }, Message: { // 必須 Body: { // 必須 Text: { Charset: 'UTF-8', Data: `投稿内容:${res.data.createPost.content}\n投稿日時:${new Date(res.data.createPost.timestamp)}`, }, }, Subject: { Charset: 'UTF-8', Data: '投稿しました' }, }, Source: 'SENDER_EMAIL_ADDRESS', // From・必須 } // 2.リージョンを設定 AWS.config.update({ region: "ap-northeast-1" }) // 3.送信処理 const ses = new AWS.SES() try { await ses.sendEmail(params).promise() console.log("Success to Send an Email") return } catch (e) { console.log(`Failed to Send an Email: ${e}`) return } return post; };送信結果
まとめ
今回はSESでメールの送信を実装しましたが、Lambdaに権限を追加すれば他のAWSのサービスも利用できそうです。
SESには、今回使っていない設定やテンプレートなどがあるようなので、カスタマイズしたい方はこちらを参考にしてみてください。参考
使用した E メールの送信Amazon SES
Lambda と Amazon SES を使用して E メールを送信するにはどうすればよいですか?
- Miyata Koki -
O:inc.でAmplify×React×React Nativeを使用して開発しています。大学のゼミでは統計学をPythonで行っています。
インターンやゼミで学んだ情報を発信していくので、フォロバするのでぜひこちらのアカウントのフォローお願いします!
- 投稿日:2021-03-22T13:34:08+09:00
ProxyベースのReact状態管理ライブラリ「Valtio」v1リリース
Valtioがv1.0.0になりました!
![]()
ぜひ試しにでも使ってみてください。
基本的に不具合等の対処が一通り終わって安定してきたのでv1になったのですが、一つだけ隠し機能だったものがオープンになりました。
useProxyマクロv0.7.1までは
useProxyは本体から提供されていましたが、v0.8.0からはuseSnapshotに改名しました。中身は変わっていません。代わりに
useProxyはマクロとして提供されるようになりました。babel-plugin-macrosを使っているのですが、Create React Appを使っている場合はすでに組み込まれています。この
useProxyマクロを使うと、import { useProxy } from 'valtio/macro' const Component = () => { useProxy(state) return ( <div> {state.count} <button onClick={() => ++state.count}>+1</button> </div> ) }と言うコードが、次のように変換されます。
import { useSnapshot } from 'valtio' const Component = () => { const snap = useSnapshot(state) return ( <div> {snap.count} <button onClick={() => ++state.count}>+1</button> </div> ) }
useProxyマクロを使うと、snapshotをほとんど意識せずにコーディングすることができます。snapshotの概念がなくなるわけではありませんが、snapshotの扱いは癖があるので、マクロが使えるケースでは役立つでしょう。ちなみに、eslint-plugin-valtioもあります。おわりに
valtioのv1リリースが完了したので、次はjotai。こっちは大物。
https://github.com/pmndrs/jotai/issues/333React開発者向けオンラインサロン「React Fan」の紹介
最後に、私が主催している「React Fan」というコミュニティをお知らせします。テキストチャットでコミュニケーションできるSlackのワークスペースを用意しています。Slackへの参加は無料ですので、ご興味がある方はぜひご参加ください。詳しくは、下記のページをご参照ください。
React開発者向けオンラインサロン「React Fan」の入り口ページ
Slackへの招待リンクも上記ページにあります。
- 投稿日:2021-03-22T10:50:28+09:00
DjangoとReactで作成したアプリにDockerを組み込む
Dockerとは
一言で言うとコンテナ型のアプリケーション実行環境のこと。
DockerがあればどのPCからでも、簡単にそのアプリを実装できる環境を構築することができる。今回やること
前回私が開発したアプリにDockerを組み込んで環境構築を容易にしていく。
そのアプリの開発記事↓
DjangoとReactでPDCAアプリを作る その1作業の流れ
1.requirements.txtの作成
2.Django用Dockerfileの作成
3.nodejs用Dockerfileの作成
4.docker-composeの作成
requirements.txtの作成
完成したアプリのディレクトリ下で以下のコマンドを実行するとそのアプリでインストールしたライブラリをrequirements.txtにまとめることができる
pip freeze > requirements.txtなお、アプリ開発を行うにあたって
Virtualenvを使って、専用の開発環境を準備した方が良い。
そうしてから取り組めば、そのアプリ開発でインストールしたライブラリだけをrequreiments.txtに落とし込むことができる。virtualenvについての記事↓
venv: Python 仮想環境管理Django用Dockerfileの作成
# pythonの基本的な環境をubuntuで構築している↓↓ FROM ubuntu:18.04 RUN apt-get -y update \ && apt-get -y upgrade \ && apt-get install -y locales curl python3-distutils \ && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py \ && python3 get-pip.py \ && pip install -U pip \ && mkdir /code \ && rm -rf /var/lib/apt/lists/* \ && localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 ENV LANG en_US.utf8 # ↑↑ # 作成したrequirementsをコンテナ側へcopy COPY ./requirements.txt /requirements.txt # コンテナ側でアプリに必要なライブラリをインストール RUN pip install -r /requirements.txt # アプリを置くためのディレクトリを作成 RUN mkdir /workapp # 起動時に最初に開かれるディレクトリを設定 WORKDIR /workapp # 作成したアプリをコンテナ側へcopy COPY ./workapp /workappnodejs用Dockerfileの作成
FROM node:10.13-alpinedocker-composeの作成
docker-composeとは、
dockerでこのコンテナを立てる際に使うであろうdockerコマンドを1つのファイルにまとめてくれるツール
version: '3' services: app: build: context: . tty: true stdin_open: true ports: - "8000:8000" # コンテナ側から実際の環境側にあるアプリを参照する volumes: - ./workapp:/workapp command: > sh -c "python3 manage.py migrate && python3 manage.py runserver 0.0.0.0:8000" depends_on: - react react: build: context: . dockerfile: "./Dockerfile-nodejs" volumes: - ./work_react:/work_react command: > sh -c "cd work_react && npm start" ports: - "3000:3000"dockerを起動してアプリディレクトリ下で、以下のコマンドを実行する
docker-compose upこれで無事、djangoとReactで開発したアプリにDockerを組み込むことができた?
今後の展望
今回は、DBをsqliteのままにしてDockerを組み込んだので、次回は、postgresSQLを用いて組み込めるようにしたい。
また、nginx等のwebサーバーも用いて、開発現場さながらのDockerコンテナを作成したいと考えているここまで読んでくださりありがとうございました?♂️?♂️
また、Twitterでも日々の積み上げや、プログラミング学習についてのツイートをしておりますので、よかったらフォローと応援の程よろしくお願いします!?♂️
Twitterアカウント↓
健将@WEBエンジニア×明大生
- 投稿日:2021-03-22T09:35:04+09:00
ポートフォリオ(チャットアプリ)について
どんなアプリか
『業務連絡のレスが早い人ほどポイントが貯まる(仕事のできる信頼が可視化される)チャットアプリ』
- メールアドレスでのユーザー登録機能
- 個人間でのチャット機能
- コンタクトを承認し合わないとメッセージ送受信できない
- 承認し合ったユーザーのみチャットリストに表示される
- リアルタイムでユーザーがオンラインかオフラインかがわかる機能
- 相手の任意で送られてくる”即レスしてほしいメッセージ”に1時間以内に返信することでポイントが加算される機能
- リアルタイムで更新されるユーザー情報の事前検索機能
なぜこのアプリを作ったか
昨今特にリモートワークがうたわるようになったビジネスシーンにおいて、メールの返信が早い事は、一つの信頼になります。
逆に返信が遅いというのは、コミュニケーションの流れが止まり、ビジネスも停滞してしまうので良くありません。
この事実を裏付ける根拠として、あらゆるビジネスパーソンの方が「即レス」の重要性を仰っています。
https://mynavi-agent.jp/dainishinsotsu/canvas/2021/01/4-1.html#sec5
https://ameblo.jp/nishino-akihiro/entry-12608672747.html
https://note.com/bookadviser/n/n13a3f84a2fbe
https://www.lidix.co.jp/blog/entry/2020/07/09/073000/6/
https://fuantensyoku.com/me-ru-hensin-osoi/
これだけ語られている議論であるのに、まだ具体的な解決に至っていないのはなぜか、どこに問題があるかを考え、解決策の一つの提案としてこのアプリを作りました。この問題のネックは、
返信が早い人に明確なうまみが少ないことと、事前に返信が早い人が可視化されないことにあると考え、
逆にこの二つをクリアにするコミュニケーションツールがあれば、この問題を解決できるのではないかと仮説を立てました。
円滑なリモート・コミュニケーションが取れれば、仕事もスムーズにすすむ。
ただ、やはり返信が早い人もいれば遅い人もいる。そして、早いかどうかは一緒に実際に仕事をしてみないとわからない。
そこで、
即レス力が事前に分かり、さらに返信が早いほどポイントが貯まるシステムにすれば、1. 一緒に仕事をする前や、採用時に、相手の返信の早さが分かり、
2. さらに逆の立場からだと、返信の早さをアピールする材料にできる、そしてそのシステムによって、
3. 普段あまり返信が早くない人でも、即レスを意識できる、
そしてこのアプリでそれらの問題を解決できれば、
4. 同じ会社内に限らず、社外提携や、フリーランスにまで、ビジネスの活性が広がるのではないか
と考え、開発に至りました。
どんな技術を利用したのか、またその理由
- フロントエンド
- React
- React Router
- React Redux
- Redux Thunk
- バックエンド
- Firebase
自分の技術面での話になるのですが、僕はReactを使って簡単な自己紹介サイトは作れるようになったので、
次の段階として、今まで学習してきたRouter、Redux、Thunkを使って、データベースと絡んだSPAを作りたいと考えました。
手軽さとドキュメントの読みやすさ、情報の多さを考えて、バックエンド機能にFirebaseを使用することにすることにしました。
Firebaseを選んだ1番の理由は、DBの自動更新を検知する機能があり、それを応用して手軽にチャットアプリを作れるということを知ったからです。開発過程ダイジェスト
まず、土台であるチャットアプリの作り方を学ぶため、いくつかのアプリを模倣して作ってみることにしました。
- 『Firebase Webコードラボ 』をドキュメントを読み進めながらアプリ制作
- 『React Chat App with React Hooks, redux, Firebase Firestore and Authentication』で英語字幕を見ながら、アプリ制作
その他、
- こちらのGitHubを見たり、
- Firebase公式ドキュメントを読みながら、
いくつか既存のものを真似ながらいくつか作ってみて、自分の思い描く実装にあった機能を取り入れながら、ポートフォリオの土台が完成。
次に、今回のメイン機能である返信が早いほどポイントが貯まるシステムですが、そのルール設定に少し悩みました。
早ければ早いほどポイントを高くしてしまうと、実際に使うときに競争感を覚え、息苦しさを感じる、
かといって、24時間以内とかにすると、本当に返信の早い人が正当に評価できないと考え、「1時間以内の返信で一律1ポイント」とルールを決めました。そして全ての返信で即レスを促すのではなく、送信するユーザーが適宜、早く返信して欲しいと思うメッセージに
ユーザーの任意で「ポイントチャンス」を付与できることにしました。当初はタイマーAPIを自作しようと考えていましたが、返信時間とその一つ前のメッセージの送信時間の時差を計算すれば、同期処理で簡単に済むことに気づき、
https://gray-code.com/javascript/calculate-the-difference-between-two-dates-and-times/
この記事を主に参考にして、返信時差が1時間以内であるかどうかを検知し、ポイントを加算するシステムを作りました。
そして、コンタクトの申請承認の前に、事前にその人のポイント情報などをリアルタイムで確認できる『ユーザー検索機能』、
誰でもかれでもメッセージを送れてしまうと、ポイントシステムの秩序が乱れると考え、
『コンタクト承認し合わないとチャットできない機能』と、『承認したユーザーのみチャットリストに表示される機能』をさらに追加することに。
ここは腕試し的にかなり自己流で作ってしまったので、もしかすると他にもっと効率的なコードがあるはずであるのが、少し反省点なので、
今後、いろんなコードを参考にしながら、リファクタリングを進めて行こうと思います。つまずいたところと、それをどう乗り越えたか
- HooksのuseEffectがなかなか使い方が難しく、挙動は正しくてもなぜかエラーが吐き出される
- → 第二引数の配列に、内部で使う、外部の定数や関数を入れたり、あえて独自のuseCallback()にラップしたりして、エラーを回避しました。
- https://ja.reactjs.org/docs/hooks-effect.html
- https://ja.reactjs.org/docs/hooks-reference.html
- https://teratail.com/questions/278542
- https://qiita.com/caocao/items/c6960fcf4a2e43c37b04
- https://stackoverflow.com/questions/57084113/interval-inside-react-useeffect-store-it-in-a-useref-hook-to-preserve-value-ov
- コンタクト申請承認情報をDBにどう保持させておくか
- はじめはuserそれぞれのdocumentに「自分が申請中のuserID」「自分の承認次第のuserID」「申請・承認し合っているuserID」を羅列しようとしていましたが、
この方法だと、一つのdocumentの情報が長くなるし、もともと保持していた「アカウント作成日」「総ポイント数」などのデータが見づらくなるという問題が出ました。- → そこでいっそ別collectionに、ユーザー1とユーザー2の関係(ユーザー1が申請中なのか、その逆なのか、もしくは承認が住んでいるのか)を単位に情報を保持するdocumentを作ることにし、
これによって、検索もかけやすくなり、ひとつひとつのdocumentが簡潔になりました。- Firestoreのデータベースアクセス権限周りで、ログインユーザーのみ有効にしているが、ログアウト時にコンソールにエラーが出る
- → これは実はまだ解決に至っていません。
しかし、ログアウトしているユーザーはアクセスできない、という意図通りの挙動で、エラーは出つつも利用に問題はなさそうなので、現在進行形で対策を見送っています。- https://firebase.google.com/docs/firestore/security/rules-conditions?hl=ja
- https://flattsecurity.hatenablog.com/entry/firestore_security_rules
- https://qiita.com/hiroki-harada/items/99d13efe432eb89e9391
- https://qiita.com/hibohiboo/items/7af59b6d0d9df98d96c4
今後改善したい点、実装したい機能
実装したい機能
- もっとユーザーの即レス力を正確にするため、週間での総オンライン時間、ポイント獲得数のデータ表示
- 即レス時間はいいものの、その返信内容が適切だったかを判断するため、ポイント獲得時に相手から返信内容をGood/Bad/NothingSpecialで評価される(その総数もデータ表示)
- 投稿日:2021-03-22T08:01:13+09:00
【React】Reactで同じモーダルを使ってURLを振り分ける
前提
以下のように同じモーダルウィンドウを使って新規登録、ログイン、ログアウトの処理を実装したい
結論
navigationを使うことで対応。
実装内容
①モーダルを開く処理をLinkごとに分ける
以下のように、新規登録・ログイン・ログアウトそれぞれモーダルを開くためのメソッドを切り分ける。
ここは引数を使うと楽な気がするが一旦このまま進める。// 新規登録・ログイン・ログアウトでモーダルの表示を分けるために別メソッドとして定義 openSignUpModal() { this.setState ({ showModal: true, content: 'SignUp' }) this.props.history.push("/users/sign_up"); } openSignInModal() { this.setState ({ showModal: true, content: 'SignIn' }) this.props.history.push("/users/sign_in"); } openSignOutModal() { this.setState ({ showModal: true, content: 'SignOut' }) this.props.history.push("/users/sign_out"); } // モーダルを閉じる。contentは空文字列にリセット closeModal() { this.setState ({ showModal: false, content: '' }) this.props.history.push("/"); }②各モーダルを開くためのリンクにそれぞれのメソッドを設定する
<HeaderLink onClick={this.openSignUpModal}> 新規登録 </HeaderLink> <HeaderLink onClick={this.openSignInModal}> ログイン </HeaderLink> <UserModal show={this.state.showModal} close={this.closeModal} content={this.state.content} signIn={this.successToSignIn}/> {/* stateのcontentでログインと新規登録を分岐 */}ログアウトボタンはログインしているときのみ表示
<HeaderLink onClick={this.openSignOutModal}> ログアウト </HeaderLink> <UserModal show={this.state.showModal} close={this.closeModal} content={this.state.content} signOut={this.successToSignOut}/>こうすることで各ボタンごとにstateの更新処理を分け、URLも別々にnavigationできる。
そしてstateの値に応じてモーダルの表示内容を切り替えることで快適なnavigationを実現参考
navigationについて
https://qiita.com/TsutomuNakamura/items/34a7339a05bb5fd697f2#navigate
- 投稿日:2021-03-22T01:08:10+09:00
React基礎
Reactの知識定着の為の忘備録
PC: Mac
JSX
マークアップとロジックを両方含む疎結合の「コンポーネント」という単位を用いる為にReactがJavaScriptの構文を拡張したものである。
要は簡単にHTMLとJSを1つのプログラムを書く様に併用できるようにしたもの!
{}でJavaScriptの要素をHTMLに入れ込むことが可能const name = 'Josh Perez'; //{}の中にJSを埋め込む const element = <h1>Hello, {name}</h1>; //出力:Hello, Josh Perez ReactDOM.render( element, document.getElementById('root') );また関数や関数の結果も埋め込むことが可能
function formatName(user) { return user.firstName + ' ' + user.lastName; } const user = { firstName: 'Harper', lastName: 'Perez' }; const element = ( <h1> //userを引数にとり、formatName関数の返り値を取得 Hello, {formatName(user)}! </h1> );JSXも式である為、if,for,変数に代入,引数,返り値等、柔軟に対応ができる
タグがからの場合は閉じタグを省略できる
const element = <img src={user.avatarUrl} />;またJSXはレンダー前にエスケープされる為、インジェクション攻撃にも対応している
自分のアプリケーションで明示的に書かれたものではないあらゆるコードは、注入できないことが保証され、レンダーの前に全てが文字列に変換される。XSS (cross-site-scripting) 対策がされている。
- 投稿日:2021-03-22T00:41:21+09:00
Docker + React (Typescript) + Rails6 環境構築
Summary
バックエンド Rails API & フロントエンド React & Docker の環境を実現したので手順をメモしておく
- Rails 初期設定ファイル作成
- Rails & React 用のDocker関連ファイル作成
- docker-compose.yml 作成
- docker コマンド実行
- database.yml の変更
- docker-compose で起動
ファイル構成
1. Rails 初期設定ファイル作成
Gemfilesource 'https://rubygems.org' gem 'rails', '=>6'Gemfile.lock# 空2. Rails & React 用のDocker関連ファイル作成
Rails
DockerfileFROM ruby:2.7.2 # Rails6 からは以下のインストールが必要 # https://yarnpkg.com/lang/en/docs/install/#debian-stable RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \ apt-get update -qq && apt-get install -y nodejs postgresql-client vim && \ apt-get install -y yarn && \ apt-get install -y imagemagick && \ apt-get install -y libvips-tools && \ apt-get install -y locales RUN curl -sL https://deb.nodesource.com/setup_7.x | bash - && \ apt-get install nodejs RUN mkdir /myapp WORKDIR /myapp COPY Gemfile /myapp/Gemfile COPY Gemfile.lock /myapp/Gemfile.lock RUN bundle install COPY . /myapp COPY entrypoint.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] EXPOSE 3000 CMD ["rails", "server", "-b", "0.0.0.0"]entrypoint.sh#!/bin/bash set -e # Remove a potentially pre-existing server.pid for Rails. rm -f /myapp/tmp/pids/server.pid # Then exec the container's main process (what's set as CMD in the Dockerfile). exec "$@"React
DockerfileFROM node:14.16.0-alpine3.10 WORKDIR /usr/src/app3. docker-compose.yml の作成
docker-compose.ymlversion: "3.9" services: db: image: postgres volumes: - postgres-data:/var/lib/postgresql/data environment: - POSTGRES_PASSWORD=password api: build: context: ./api/ dockerfile: Dockerfile command: /bin/sh -c "rm -f /myapp/tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" volumes: - ./api:/myapp - ./api/vendor/bundle:/myapp/vendor/bundle environment: TZ: Asia/Tokyo RAILS_ENV: development ports: - 3000:3000 depends_on: - db front: build: context: ./front/ dockerfile: Dockerfile volumes: - ./front:/usr/src/app command: sh -c "cd frontend && yarn start" ports: - "8000:3000" volumes: postgres-data: driver: local4. docker コマンド実行
$ docker-compose run api rails new . --force --no-deps --database=postgresql --api $ docker-compose build # yarn でインストール、Typescript 対応 $ docker-compose run --rm front sh -c "yarn create react-app frontend --template typescript"5. database.yml の変更
config/database.ymldefault: &default adapter: postgresql encoding: unicode host: db username: postgres password: password pool: 5 development: <<: *default database: myapp_development test: <<: *default database: myapp_test production: <<: *default database: myapp_production username: myapp password: <%= ENV['MYAPP_DATABASE_PASSWORD'] %>6. docker-compose で起動
$ docker-compose up -d $ docker-compose run api rails db:create参考


