20220114のReactに関する記事は4件です。

Reactの環境構築

いつもyarn startで失敗してできなかったReactの環境構築 新しいノートパソコンを買ったので頑張ってみた記録 今回の流れはこんな感じです Visual Studio Codeをインストール Node.jsをインストール yarnをインストール create-react-appでReactアプリを作る yarn startしてみる yarn startできないエラーを解決する もう一度yarn startしてみる 基本情報 OS:Windows 10 1. Visual Studio Codeをインストール まずは以下リンクからVS Codeをインストール https://code.visualstudio.com/download インストーラは全部同意、他は何も気にせずok 2. Node.jsをインストール 以下のリンクからLTS版をインストール https://nodejs.org/ja/ ここのインストーラも同意、ok インストール終わったらコマンドプロンプトで以下のコマンドを実行 バージョンが返ってくればok $ node -v v16.13.2 3. yarnをインストール 仕事ではnpmじゃなくてyarnを使ってるのでyarnにしたい! ので以下のコマンドをコマンドプロンプトで実行 $ npm install --global yarn 完了したらコマンドプロンプトで以下のコマンドを実行 これもバージョンが返ってくればok $ yarn --v 1.22.17 いったん環境構築は完了したので、アプリ作って動かしてみる 4. create-react-appでReactアプリを作る Reactのひな型作ってくれるコマンド使ってアプリ作ってみる。 フォルダ名は「helloworld」 とりあえずCドライブ直下に「Program」フォルダを作ってそこに作る まずはフォルダに移動 $ cd C:\Program $ Program> 移動出来たら以下のコマンドを流す $ Program> npx create-react-app helloworld うまくいけばProgramフォルダの中にhelloworldフォルダができる 5. yarn startしてみる アプリ作れたので、動かしてみよう VS Codeでさっきのhelloworldフォルダを開く VS Codeのターミナルを開いて、以下のコマンドを実行 $ yarn start yarn : このシステムではスクリプトの実行が無効になっているため、ファイル C:\Users\xxx\AppData\Roaming\npm\yarn.ps1 を読み込むことができません。詳細については、「about_Execution _Policies」(https://go.microsoft.com/fwlink/?LinkID=135170) を参照してください。 発生場所 行:1 文字:1 + yarn start + ~~~~ + CategoryInfo : セキュリティ エラー: (: ) []、PSSecurityException うまくいくはず、、だけどやっぱりエラーが出た… 6. yarn startできないエラーを解決する いつも詰まっていたところにたどり着きました… ですが今回はあきらめません 色々調べて今回参考にしたのはこちら http://xn--u9j0md1592aqmt715c.net/get-executionpolicy/ 原因は「セキュリティ上の理由で、スクリプトの実行が無効化されている」ためでした ここからはWindows PowerShellの出番です 下の虫眼鏡でWindows PowerShellを検索し、右クリックして「管理者として実行」 まずは権限が何か確認します PS > Get-ExecutionPolicy Restricted Restrictedは「全スクリプト実行不可」という意味だそうです なのでここをRemoteSignedに変えます 意味は「インターネット経由でダウンロードしたスクリプトのみ証明書を要求」 PS > Set-ExecutionPolicy RemoteSigned 実行ポリシーの変更 実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies のヘルプ トピック (https://go.microsoft.com/fwlink/?LinkID=135170) で説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか? [Y] はい(Y) [A] すべて続行(A) [N] いいえ(N) [L] すべて無視(L) [S] 中断(S) [?] ヘルプ (既定値は "N"): ここは「y」を入力してEnterでok 最後に代わっているかを確認 PS > Get-ExecutionPolicy RemoteSigned 無事変わりました! 7. もう一度yarn startしてみる ここまでくれば大丈夫でしょう! ドキドキしながらVS Codeでyarn startをしてみると、、、 実行できました!!! やった!! 感想 今回環境構築からアプリの実行までがうまくできたのは、「Set-ExecutionPolicyコマンドを実行するのはコマンドプロンプトではなくWindows PowerShellだと気づけたこと」です! 実行するアプリの違いで詰まってたとはお恥ずかしい… 教訓としてきちんと覚えておこうと思います 【参考】 React 開発環境構築 俺の技術メモ - PowerShellのお手製スクリプトを実行しようとした時に、赤文字が表示されて実行できない場合の対処法
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Amplifyで静的サイトをホスティング(SSG)する

概要 React/Next.js(SSG)をAmplifyにデプロイする機会があったので手順をメモ。 背景 もともとCloudFront + S3の構成でReact/Next.jsを動かす予定でしたが、リロードすると404になってしまう問題に直面したのでAmplifyへ移行しました。(Amplifyも裏ではCloudFront + S3で動いているようですがリロード問題は発生しない ← 確認済み) リロード問題の参考↓ https://qiita.com/ryokkkke/items/1478a022b220bf6e61ff https://blog.ojisan.io/s3-next-deploy/ Lambda@edgeで対応する方法もあるようですが、Amplifyでホスティングする方が簡単そうです。 また、調べるとS3でリダイレクトをかけて対応しているケースもありましたが、こちらはなぜかうまくいきませんでした。 今回は、将来的にSSRやISRしたくなった時のことも考えAmplifyへ移行を決定。 手順 AmplifyのTopページで「Host your web app」のほうの「Get started」を選択 デプロイしたいサービスのプロバイダー(Github等)を指定 デプロイしたいサービスのリポジトリ&ブランチを指定 ビルド設定を確認・追記 デプロイ AmplifyのTopページで「Host your web app」のほうの「Get started」を選択 「Host your web app」のほうの「Get started」を選択。右側ですね。 デプロイしたいサービスのプロバイダー(Github等)を指定 Amplifyにデプロイしたいプロバイダーを選択。 デプロイしたいサービスのリポジトリ&ブランチを指定 プロバイダーを選択し、認証したらデプロイ対象のリポジトリとブランチを選択。 ビルド設定を確認・追記 任意のアプリ名をつけて、ビルド設定を記載します。 ビルド設定は、コードがpushされたときに自動で走るコマンドの指定になります。 デフォルトでビルド設定を用意してくれますが、1点修正しました。 version: 1 frontend: phases: preBuild: commands: - npm ci build: commands: - npm run build // ↑ 修正 artifacts: baseDirectory: dist files: - '**/*' cache: paths: - node_modules/**/* また、このページで環境変数の設定等ができたりします。 デプロイ 最後に確認画面が表示され、問題なければ「保存してデプロイ」を選択。 フレームワークの部分にnextが表示されているので、ちゃんと認識してくれていますね。 初回のデプロイ以降も指定したブランチにPush or Mergeされれば自動でAmplifyにデプロイされます。 ドメイン設定 サイドバーの「ドメイン管理」を選択。「カスタムドメインの追加」からRoute53に設定しているドメイン追加できます。 ベーシック認証 サイドバーの「アクセスコントロール」を選択。「アクセスの管理」からIDとPasswordを設定することができます。 設定できていれば↓のような感じになります。 環境変数 ステージングと本番環境の環境変数もAmplify管理画面から簡単に設定できました。 ブランチごとに環境変数を設定後、ビルドの設定からamplify.ymlに下記等で渡します。 build: commands:  # amplifyの環境変数設定画面でORIGINを設定。 - echo "ORIGIN=$ORIGIN" >> .env あとは、 process.env.ORIGIN 上記等で使いまわせます。 参考サイト https://dev.classmethod.jp/articles/amplify-add-hosting-with-angular-app/ https://qiita.com/duplicate1984/items/6f506c724ee519ce4e4c https://zenn.dev/leaner_tech/articles/20210630-replace-spa-with-amplify#%E8%A4%87%E6%95%B0%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E3%81%AE%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4%E3%81%A8%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Amplify StudioのFigma+React連携ハンズオン

概要と背景 Amplify StudioのFigma連携ができるようになったと聞いたので、試してみました。 AWS Amplify Studio - 最小限のプログラミングでFigmaからフルスタックのReactアプリを実現 | Amazon Web Services 想定読者 Amplify StudioのFigma-React連携どんな感じ?って方。 環境 Amplify CLI 7.6.9 前提知識 基本知識がある方は読み飛ばして大丈夫です。 AWS Amplify とは 簡単に言うと、フロントエンド駆動でのフルスタックアプリケーション開発が可能なツール。 Amplifyを使用することで、API, Lambda, Storage, Auth, HostingといったWebアプリケーションに必要な基本的なものが簡単に管理できます。 AWS Amplify Studio とは 私もこちらは初めて触るので、まずは公式の説明を引用して記載します(英語しかなかったので翻訳はGoogle様にお願いしました)。 AWS Amplify Studio | Visually Build Extensible, Full-Stack Apps Fast AWS Amplify Studioは、開発者が完全なWebアプリとモバイルアプリを数週間ではなく数時間で簡単に構築して出荷できるようにするビジュアル開発環境です。Amplify Studioを使用すると、アプリのバックエンドをすばやく構築し、リッチユーザーインターフェイス(UI)コンポーネントを作成し、最小限のコーディングでUIをバックエンドに接続できます。Amplify Studioは、すべてのUIとインフラストラクチャアーティファクトをコードとしてエクスポートするため、アプリのデザインと動作を完全に制御できます。クラウドやAWSの専門知識を必要とせずに、より速く出荷し、スムーズに拡張できます。 Amplifyをよりよく使うための開発環境、という位置付けのようです。 その特徴の1つとして、Figma連携がある感じ。 React とは JavaScriptのフレームワークです。特徴的なのはHTMLライクにコンポーネントが記述できる、JSXの仕様ですかね。 私もまだざっとハンズオンを学習した程度なので、これから学習していきます。 Vueはそこそこ経験があるのですが、Reactの方がすっきりかける印象です。 Figma とは ワイヤーフレームなどを作成できるツールです。 私はデザイナーさんの作成したものを見るだけでほとんど使ったことがないので、細かい説明は省略させていただきます… (勉強しなくちゃ) 手順 AWS Amplify Studio - 最小限のプログラミングでFigmaからフルスタックのReactアプリを実現 | Amazon Web Services に記載の手順を元にハンズオンとして進めてみます。 GraphQL APIバックエンドとReactフロントエンドを持つ、サンプルReactアプリケーションをデプロイする 記事内のサンプルプロジェクトをデプロイ用のリンクが用意されていたので、ポチっと作成。 Amplify Studioを起動する しばらく待つと Studio を起動する が表示されました。 データモデル、データを作成 記事内容と同じ通りデータモデルを作成。Save and Deployで保存。 右上のDeploying...を押下するとCloudFormationのステータスも確認できました。 ランダムシードデータを作成。 Figma側でAWS Amplify UI Kitをインストール Communityで検索したら出てきたので、Duplicateで手元へ。 Amplify Studioで同期 Amplify Studio側でFigmaのURLを指定したら、Importすることができました! Sync with Figmaをクリックするたびに、同期を取る仕様のようです。 手元のコードに反映 amplify pullしてみると、失敗。 $ amplify pull --appId <appId> --envName staging Invalid feature flag configuration These feature flags are defined in the "amplify/cli.json" configuration file and are unknown to the currently running Amplify CLI: - project - graphqltransformer.transformerversion - graphqltransformer.suppressschemamigrationprompt - auth.useenabledmfas This issue likely happens when the project has been pushed with a newer version of Amplify CLI, try updating to a newer version. Learn more about feature flags: https://docs.amplify.aws/cli/reference/feature-flags versionが古かったので更新! $ amplify version 6.3.0 $ amplify version 7.6.9 再pull OK。 $ amplify pull --appId <appId> --envName staging Opening link: https://**********/staging/verify/ ✔ Successfully received Amplify Studio tokens. Amplify AppID found: ************. Amplify App name is: amplify-homes Backend environment staging found in Amplify Console app: amplify-homes ? Choose your default editor: Visual Studio Code ? Choose the type of app that you're building javascript Please tell us about your project ? What javascript framework are you using react ? Source Directory Path: src ? Distribution Directory Path: build ? Build Command: npm run-script build ? Start Command: npm run-script start ✔ Synced UI components. GraphQL schema compiled successfully. Edit your schema at <DIR_ROOT>/amplify/backend/api/amplifyhomes/schema.graphql or place .graphql files in a directory at <DIR_ROOT>/amplify/backend/api/amplifyhomes/schema Successfully generated models. Generated models can be found in <DIR_ROOT>/src ? Do you plan on modifying this backend? No Added backend environment config object to your project. Run 'amplify pull' to sync future upstream changes. src/ui-componens内にFigmaで定義したコンポーネント群が作成されました。 $ ls src/ui-components/ Ampligram.jsx CardF.jsx Features2x3.jsx HeroLayout3.jsx ProfileA.jsx Ampligram.jsx.d.ts CardF.jsx.d.ts Features2x3.jsx.d.ts HeroLayout3.jsx.d.ts ProfileA.jsx.d.ts CardA.jsx CardG.jsx Features4x1.jsx HeroLayout4.jsx SideBar.jsx CardA.jsx.d.ts CardG.jsx.d.ts Features4x1.jsx.d.ts HeroLayout4.jsx.d.ts SideBar.jsx.d.ts CardB.jsx ContactUs.jsx FeaturesText2x2.jsx MarketingFooter.jsx SocialA.jsx CardB.jsx.d.ts ContactUs.jsx.d.ts FeaturesText2x2.jsx.d.ts MarketingFooter.jsx.d.ts SocialA.jsx.d.ts CardC.jsx EditProfile.jsx FormCheckout.jsx MarketingPricing.jsx SocialB.jsx CardC.jsx.d.ts EditProfile.jsx.d.ts FormCheckout.jsx.d.ts MarketingPricing.jsx.d.ts SocialB.jsx.d.ts CardD.jsx FAQItem.jsx HeroLayout1.jsx NavBar.jsx index.js CardD.jsx.d.ts FAQItem.jsx.d.ts HeroLayout1.jsx.d.ts NavBar.jsx.d.ts CardE.jsx Features2x2.jsx HeroLayout2.jsx ProductDetail.jsx CardE.jsx.d.ts Features2x2.jsx.d.ts HeroLayout2.jsx.d.ts ProductDetail.jsx.d.ts 試しにCardDコンポーネントの中身をみてみます。 CardD.jsx /*************************************************************************** * The contents of this file were generated with Amplify Studio. * * Please refrain from making any modifications to this file. * * Any changes to this file will be overwritten when running amplify pull. * **************************************************************************/ /* eslint-disable */ import React from "react"; import { getOverrideProps } from "@aws-amplify/ui-react/internal"; import { Image, Text, View } from "@aws-amplify/ui-react"; export default function CardD(props) { const { overrides: overridesProp, ...rest } = props; const overrides = { ...overridesProp }; return ( <View width="320px" height="320px" position="relative" padding="0px 0px 0px 0px" {...rest} {...getOverrideProps(overrides, "View")} > <Image width="320px" height="320px" position="absolute" left="0px" top="0px" borderRadius="8px" padding="0px 0px 0px 0px" {...getOverrideProps(overrides, "View.Image[0]")} ></Image> <Text fontFamily="Inter" fontSize="32px" fontWeight="700" color="rgba(255,255,255,1)" lineHeight="40px" textAlign="center" display="flex" direction="column" justifyContent="flex-start" position="absolute" left="101px" top="240px" padding="0px 0px 0px 0px" children="Explore" {...getOverrideProps(overrides, "View.Text[0]")} ></Text> </View> ); } CardD.jsx.d.ts /*************************************************************************** * The contents of this file were generated with Amplify Studio. * * Please refrain from making any modifications to this file. * * Any changes to this file will be overwritten when running amplify pull. * **************************************************************************/ import React from "react"; import { EscapeHatchProps } from "@aws-amplify/ui-react/internal"; import { ViewProps } from "@aws-amplify/ui-react"; export declare type CardDProps = React.PropsWithChildren<Partial<ViewProps> & { overrides?: EscapeHatchProps | undefined | null; }>; export default function CardD(props: CardDProps): React.ReactElement; あとはこのコンポーネントを使用するだけというところまで確認できました!! まとめ コンポーネントのReactがばばんと作成されて、大変便利だと感じました!!! 一方で実務レベルで考えると気になることもいくつかありましたので挙げておきます。 Figmaの同期が手動のみに見えたので、それだと、古いUIコンポーネントを使用していることに気づかなさそう。 Amplify Studioでの変更がFigmaに反映されなさそう 基本デザイン変更はFigma起点になるのかな? ハンズオンのコンポーネント管理レベルならよさそうだけど、ページ全体をこの方法で管理するとなると、機能仕様変更でちょっとデザインを変えたい時もデザイナーさん経由でFigma修正が発生する形になるのかな… デザイン周りは詳しくないので誤解があるかもしれませんが、 コード生成もしてくれるStorybookみたいな立ち位置が今のところ一番しっくりきています。 全面的に使用すると細かい修正が不便だったり、スピード感が落ちたりといったことが出てきそうですね。 プロダクトで使用しましたら、フィードバックを追記していきたいと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[React]ボタン押下で動的にformを追加する

ざっくり説明 1年前に下書きしてたやつを掘り返した。 やり方は大まかにこんな感じ。 buttonをclickでformを追加 formの内容がchangeしたときに値をsetState コード書くよ 前提として ここから始まります。 import React from 'react'; class TaskForm extends React.Component { constructor(props){ super(props); this.state={ tasks: [ { task_name: "", start_datetime: "", end_datetime: "", task_memo: "", } ], }; } render() { return ( <div className="task-form"> <input type="text" placeholder="task_name" name="task_name" value={task.task_name} /> <input type="datetime-local" placeholder="start_datetime" name="start_datetime" value={task.start_datetime} /> <input type="datetime-local" placeholder="end_datetime" name="end_datetime" value={task.end_datetime} /> <textarea placeholder="task_memo" name="task_memo" value={task.task_memo} /> </div> ); } } export default TaskForm; 本題 button追加 render() { return ( <div className="task-form"> <input type="text" placeholder="task_name" name="task_name" value={task.task_name} /> <input type="datetime-local" placeholder="start_datetime" name="start_datetime" value={task.start_datetime} /> <input type="datetime-local" placeholder="end_datetime" name="end_datetime" value={task.end_datetime} /> <textarea placeholder="task_memo" name="task_memo" value={task.task_memo} /> <button type="button" onClick={() => this.addNewTask()}>+</button> </div> ); } addNewTask()記述 addNewTask(){ this.setState({ tasks: [...this.state.tasks, { task_name: "", start_datetime: "", end_datetime: "", task_memo: "" }] }); } map関数導入 render() { return ( <div className="task-form"> { this.state.tasks.map((task, index) => { return ( <div key={index}> <input type="text" placeholder="task_name" name="task_name" value={task.task_name} /> <input type="datetime-local" placeholder="start_datetime" name="start_datetime" value={task.start_datetime} /> <input type="datetime-local" placeholder="end_datetime" name="end_datetime" value={task.end_datetime} /> <textarea placeholder="task_memo" name="task_memo" value={task.task_memo} /> </div> ) }) } <button type="button" onClick={() => this.addTask()}>+</button> </div> ); } 入力した値を表示 onChange render() { return ( <div className="task-form"> { this.state.tasks.map((task, index) => { return ( <div key={index}> <input type="text" placeholder="task_name" name="task_name" value={task.task_name} onChange={(e) => {this.handleChange(e, index)}}/> <input type="datetime-local" placeholder="start_datetime" name="start_datetime" value={task.start_datetime} onChange={(e) => {this.handleChange(e, index)}}/> <input type="datetime-local" placeholder="end_datetime" name="end_datetime" value={task.end_datetime} onChange={(e) => {this.handleChange(e, index)}}/> <input type="url" placeholder="url" name="url" value={task.url} onChange={(e) => {this.handleChange(e, index)}}/> <textarea placeholder="task_memo" name="task_memo" value={task.task_memo} onChange={(e) => {this.handleChange(e, index)}}/> </div> ) }) } <button type="button" onClick={() => this.addTask()}>+</button> </div> ); } handleChange() handleChange(e, index){ this.state.tasks[index][e.target.name] = e.target.value; this.setState({tasks: this.state.tasks}); } 参考 1年前で不確かだけど外国人の方のYoutubeです。 react dynamic form とかで検索してたはず。 それっぽいのおいておきます。。。 参考にさせていただいた方すみません。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む