20200802のReactに関する記事は7件です。

配列の基礎

配列についてまとめます.
Reactの勉強をしているので,記述例がReactの構文になっています.

配列の作り方

基本的な文法は,var 配列名 = []です

記述例

import React, { Component } from 'react';

class App extends Component{
  render(){
    const array = [1,2,3,4,5,6,7,8,9,10];
    return(
      <div>
        <h1>{array}</h1>
      </div>
    )
  };
}

export default App;

image.png

ある要素を表示する方法

配列から,ある要素を表示するためには配列名[順番]です.
<注意>順番は0から数えます!

記述例

import React, { Component } from 'react';

class App extends Component{
  render(){
    const array = [1,2,3,4,5,6,7,8,9,10];
    return(
      <div>
        <h1>{array[0]}</h1>
        <h1>{array[1]}</h1>
        <h1>{array[2]}</h1>
        <h1>{array[3]}</h1>
        <h1>{array[4]}</h1>
        <h1>{array[5]}</h1>
        <h1>{array[6]}</h1>
        <h1>{array[7]}</h1>
        <h1>{array[8]}</h1>
        <h1>{array[9]}</h1>
      </div>
    )
  };
}

export default App;

image.png

配列の要素の更新・追加・削除

更新

更新するためには,配列名[順番]=更新させた要素

追加

追加するためには,
 ①配列の末尾に追加する場合,配列名.push(追加する要素)

const array = [1,2,3,4,5];
array.push(6);

image.png

 ②配列の先頭に追加する場合,配列名.unshift(追加する要素)

const array = [1,2,3,4,5];
array.unshift(0);

image.png

 ③配列の指定した場所に追加する場合,配列名.splice(無視する要素の先頭からの個数,無視しない要素のうち削除する要素の先頭からの個数,追加する要素)

const array = [1,2,3,4,5];
array.splice(2,0,3.5);

image.png

削除

削除するためには,
 ①配列の末尾の要素を削除する場合,配列名.pop()

const array = [1,2,3,4,5];
array.pop();

image.png

 ②配列の先頭の要素を削除する場合,配列名.shift

const array = [1,2,3,4,5];
array.shift();

image.png

参考

MDM web docs
Syncer

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

React hooks + Django RestFrameworkで簡単な欲しいものリストを作成

制作物について

ReactとDjango RestFrameworkの勉強のアウトプットとして非常に簡単な欲しいものリストアプリを作成しました。
バックエンドはAWS EC2にnginx環境を構築してデプロイ、フロントエンドはGithubのソースコードをS3に自動デプロイされるようにしています。
ソースコード
バックエンド 
https://github.com/s-amano/wishlist2
フロントエンド
https://github.com/s-amano/wishlist-frontend

アプリのURL
http://dbs94qexekbu1.cloudfront.net/
サンプルユーザーとして

アドレス:sample@gmail.com
パスワード:sample

でログインできます。

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

React hooks + Django RestFrameworkで欲しいものリストを作成

制作物について

ReactとDjango REST Frameworkの勉強のアウトプットとして非常に簡単なSPAを作成しました。

ソースコード
バックエンド 
https://github.com/s-amano/wishlist2
フロントエンド
https://github.com/s-amano/wishlist-frontend

アプリのURL
http://dbs94qexekbu1.cloudfront.net/
サンプルユーザーとして

アドレス:sample@gmail.com
パスワード:sample

でログインできます。

制作物の構成とその構成にした理由

実際に作ったアプリの全体的な構成となぜそのような構成にしたのかを述べていきたいと思います。

構成

バックエンドとフロントエンドは開発環境は独立させています。Route53での名前解決は行っておりません。

  • バックエンドはDjango REST FrameworkでAPIを作成
    • こちらでCORSの設定
    • ログインなどの認証はトークン認証を使用
  • フロントはcreate-react-appコマンドで開発

    • axiosでAPIを叩く
  • バックエンドとフロントエンドで別々にデプロイ

    • バックエンドはAWS EC2にnginx環境を構築
    • フロントはS3をCloudFront経由でインターネット上へ公開
    • フロントはさらに、Githubのmasterブランチにプッシュすると自動でソースコードがデプロイ

構成の理由

インターンの業務でAWS lambdaでAPIを作成することがあり、その時に使用していた言語がpythonだったので、pythonで何か作るということにしました。さらに上記のAPI作成の業務によりAPIの知識もほんの少しだけあったのでこちらのアウトプットとして、Django REST Frameworkを使おうということになりました。

最初はバックエンドのみでAPIを作ってローカルで試していただけでしたが、フロントも実装してwebアプリケーションにしようと思い、ネットで調べるとreact+DjangoRestFrameworkの構成を見つけたのでその記事を参考にreact側も実装してみました。その際にUdemyの「[基礎編]React Hooks + Django REST Framework API でフルスタックWeb開発」という動画も参考にさせていただきました。

インフラについては、スタックオーバーフローなどで別々にデプロイするのがよいみたいなことが書いてあったので、別々にググりました。Reactのデプロイに参考にした記事はこちらになります。ほとんどこの通りにやりました。Djangoのデプロイはこちらの記事を参考にしました。

一通り作ってみての感想

今回作成したアプリは非常に簡単なアプリだとは思いますが、非常に時間がかかってしまいました。もちろん自分が初心者だということもあるのですが、自分が思っている以上にアプリの作成は大変なんだなと痛感しました。

ただ今回一通り作ってみてなんとなく浅く広くフロントからバックエンド、インフラまで知識がついた気がします。しかし、なにか技術的な知識がついたというよりも、むしろエラーでつまづいた時にどのように解決したらいいか、どのように調べたらいいか、というようなことを多く学んだ気がします。
「エラーが起きて動かなかったときどうすればよいかの勉強」は自分で何かを作るのが一番いいんだなと思いました。

今回作ったアプリ自体にもまだまだ課題があります。例えばログインフォームのバリデーションだったり、セキュリティだったり欲しいものリストにおいて想定外の操作をされるとバグが起こったりということがあります。こちらは随時解消して行こうかと思っています。

次は、上記で述べたバグを解消したりさらに言えば、もう少し大きめの機能がたくさんあるWebアプリケーションを作ったり、チーム開発についても学んでいきたいです。

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

Reactでsvgをimportする方法

やりかた

npm i react-svg-loader --save-dev
import Image1 from 'react-svg-loader!./image1.svg';

↓ここを参考に
https://blog.kwst.site/201908203549/

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

Amplify Frameworkの新しい認証UIコンポーネント(@aws-amplify/ui-react)を試そう

Amplify Frameworkとは

AWSがOSSとして提供している開発プラットフォーム。CLIでコマンドを叩くだけで認証やAPI、ストレージなどをAWS上にいい感じに構築してくれるスグレモノ。

最初の環境構築方法などは他の記事やサイトに書かれているのでそちらを参照していただきたい。

ただし、今回は
npm install aws-amplify-react
でaws-amplify-reactをReactアプリに組み込むことはせず、代わりに
npm install @aws-amplify/ui-react
を叩いて@aws-amplify/ui-reactを使用する。

認証画面の表示がおかしい・・・

本題に進む前にAmplify Frameworkを触っていて起きたことについて少しだけ書くと、
数多ある「Amplify Frameworkで認証画面を爆速で作ってみよう」系の記事を参考に
胸を躍らせながらAmplifyのコマンドを叩いてAWS環境を構築し、クライアントにパッケージを入れ、
いざnpm startを快音高らかに叩いた時に悲劇が起きた。

Failed_Auth

なにこれ・・・?

やべぇ・・・同じ手順で進めたはずが、クソださ認証画面を生み出してしまった。
何か間違えてたかと虱潰しに手順を確認するも特に異常なし。
途方に暮れながらGoogle先生にお伺いを立てていると天啓が届いた。

「それレガシーですよ」

公式ドキュメントではすでにaws-amplify-reactはLegacyと書かれているではないですか!(知らんかった・・・)

AWSのブログを見ると4月にはすでに発表されてるじゃないですか!(知らんかった・・・)

というわけで自分の無知に深く恥入りながらも、早速@aws-amplify/ui-reactを使って認証機能を作っていきましょうという次第であります。

(画面が変になったのはこのLegacyのせいなのかは実はちょっとハッキリしていません・・・(小声))

まずは基本のAmplifyAuthenticator

App.js
import React from 'react';
import Amplify from 'aws-amplify';
import { AmplifyAuthenticator } from '@aws-amplify/ui-react'; 
import awsconfig from './aws-exports';

Amplify.configure(awsconfig);

const App = () => (
  <AmplifyAuthenticator>
    <div>
      My App
    </div>
  </AmplifyAuthenticator>
);

export default App;

実装はとてもシンプルで@aws-amplify/ui-reactからAmplifyAuthenticatorをApp.jsにインポートして
認証通過後の画面要素を挟んであげるだけ。

SignIn画面

SignInPage1

SignUp画面

SignUpPage1

これだけで冒頭でお見せしたクソださ認証画面ではなく、ちゃんと綺麗な認証画面が出来上がった。とりあえず一安心。

入力項目をカスタマイズ

@aws-amplify/ui-reactではSign-inやSign-upの入力項目や必須か否かをカスタマイズすることができる。

まずはSign-in画面のUsernameのカスタマイズから。

デフォルトでは任意のUsernameを入力することになっているが、ここでメールアドレスを利用可能にする。

まずはCognitoの認証方式でメールアドレスをUsernameとして利用できるようにしておく。(参考サイト

Amplify FrameworkのCLIですでにメールアドレスをUsernameとして利用可能にしておいた場合は設定不要だ。

あとは以下のように先ほど書いたAmplifyAuthenticatorのusernameAliasプロパティに"email"を渡してあげればOK。

App.js
const App = () => (
  <AmplifyAuthenticator usernameAlias="email"> {/* <- ここで設定 */}
    <div>
      My App
    </div>
  </AmplifyAuthenticator>
);

Sign-in2

先ほどのSing-in画面と比べてUsernameの項目がEmail Addressに変更されている。
ここを電話番号にしたい場合はCognitoの設定後にusernameAliasに"phone_number"を渡すことで実現できる。

次にSign-upの入力項目が多すぎるなと感じたので減らしてみよう。

App.js
import { AmplifyAuthenticator, AmplifySignUp } from '@aws-amplify/ui-react';

まずは@aws-amplify/ui-reactからAmplifyAuthenticatorに加えてAmplifySignUpをインポート。

App.js
const App = () => (
  <AmplifyAuthenticator>
    <AmplifySignUp
      slot="sign-up"
      usernameAlias="email"
      formFields={[
        {
          type: "email",
          label: "Email address",
          placeholder: "Enter your email address",
          required: true,
        },
        {
          type: "password",
          label: "Password",
          placeholder: "Enter your password",
          required: true,
        },
      ]}
    ></AmplifySignUp>
    <div>
      My App
    </div>
  </AmplifyAuthenticator>
);

export default App;

あとはAmplifySignUpを最初の画面の前にプロパティを加えて入れてあげればOK。

slotはAmplifyのUIコンポーネントをカスタマイズするために必要なプロパティ。他にもコンポーネントに合わせたslotがあるので
ここを参考に必要なslot名を入れる。(AmplifySingInならslot="sign-in"といった具合)

usernameAliasは先ほどのSign-in画面のカスタマイズの時と同様、Usernameにメールアドレスを使用可能にするプロパティ。

formFieldsは入力項目をカスタマイズするためのプロパティ。配列の中のオブジェクトによって入力項目を制御できる。

typeで入力項目の種類、labelで入力欄の上に表示される文字、placeholderで入力欄に表示されるプレースホルダー、そしてrequiredで必須項目か否かを指定することができる。

今回はメールアドレスとパスワードの2つの必須項目を設定した。

Sign-up2

これでアカウント作成が可能になったので早速作ってみる。Sign-up画面の項目を入力してCREATE ACCOUNTをクリックすると確認画面が表示される。

Confirm page

登録したメールアドレスに確認用の6桁のコードが送信されるのでそれを入力すれば確認完了。アプリにサインインできるようになる。

サインアウト

これでサインインする準備ができた。サインインできるならサインアウトも必要だ。サインアウトの実装も至って簡単。

App.js
import { AmplifyAuthenticator, AmplifySignUp, AmplifySignOut } from '@aws-amplify/ui-react';

まずはAmplifySignOutを@aws-amplify/ui-reactからインポートする。

App.js
const App = () => (
  <AmplifyAuthenticator usernameAlias="email">
    <AmplifySignUp
      slot="sign-up"
      usernameAlias="email"
      formFields={[
        {
          type: "email",
          label: "Email address",
          placeholder: "Enter your email address",
          required: true,
        },
        {
          type: "password",
          label: "Password",
          placeholder: "Enter your password",
          required: true,
        },
      ]}
    ></AmplifySignUp>
    <div>
      My App
      <AmplifySignOut /> {/* <- ここに追加 */}
    </div>
  </AmplifyAuthenticator>
);

あとは画面の好きなところにを入れてあげれば完成。

Sign out

サインインすると最初の画面に横長なSing-outボタンが表示された。

ボタンの文言を変更したいときは以下のようにbuttonTextプロパティに指定の文言を渡してあげれば変えることができる。

App.js
<AmplifySignOut buttonText="Custom Sign Out Button"/>

Sign out2

(小文字で書いても大文字になっちゃうみたい・・・)

ちょっとだけ問題点

追記(2020/8/3)

コメントにある通り、Amplifyの公式サイトにログイン画面の配置を真ん中にするCSSのテンプレートがあった。
index.cssに以下を記述することでログイン画面が真ん中に表示された。
新コンポーネントを利用する際は忘れずに記載するようにしよう。
(ずっとApp.cssの方に記載して「全然反映されねぇ…」と少し焦ったのは内緒。)

index.css
amplify-authenticator {
  display: flex;
  justify-content: center;
  align-items: center;
  flex: 1;
  height: 100vh;
}

とっても簡単に認証画面周りを構築してくれるAmplify Frameworkの新コンポーネントだが、少しだけ問題点もあった。(※追記で解決済み)

上記では認証コンポーネントのみを切り抜いてスクショしていたのでわからなかったが、実は下のように左上にデフォルトで表示されてしまうのだ。

Sing In3

Legacy版のwithAuthenticatorを使っていた場合だとデフォルトでスクリーンの真ん中に表示されていたが、新バージョンはそこまで気を利かせてはくれないらしい。

IssueもまだOpen状態なので今後改善されるのを待つしかなさそう。

App.js
<AmplifyAuthenticator usernameAlias="email" style={{ textAlign: 'center', margin: 0 }}>

こんな感じでstyleを適用してみても横方向の真ん中に設定できるくらいだった。(・・・ので誰か知恵をお貸しください(ボソッ))

ちなみに新バージョンにもwithAuthenticatorはあるので以下のように使えばサインイン画面を真ん中に表示させることはできる。

App.js
import React from 'react';
import { withAuthenticator, AmplifySignOut } from '@aws-amplify/ui-react';

const App = () => (
  <div>
    <AmplifySignOut />
    My App
  </div>
);

export default withAuthenticator(App);

ただしこれだとAmplifySingUpの入力項目カスタマイズができなかった。(調査不足でできたらゴメンナサイ・・・)

ここら辺のデザイン周りが調整されればあとは完璧かなと感じた。画面のど真ん中にこだわらない方であれば横方向の真ん中までなら配置できるので問題ないはず。

まとめ

Amplify FrameworkはCLIを操作するだけでバックエンド、フロントエンド両方をいい感じに作ってくれる便利なフレームワーク。

新しいUIコンポーネントでも手軽に項目の操作などができ、認証周りの開発はとても捗りそう。

ここで述べた他にもカスタマイズ可能な項目やコンポーネントはたくさんあるので今後も調べながら使ってみたい。

また記事中に何か不足している点などがあれば是非ご指摘いただければ助かります。

参考

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

【Next.js】 getInitialPropsの備忘

getInitialProps

↓公式
https://nextjs.org/docs/api-reference/data-fetching/getInitialProps

これはssrのときに使うって感じで書かれているんだけど、フロントのspa遷移時にも動くから注意。
というか、そっちのほうが使いやすかったりする。

const Test = ({ kkkkk }) => {
return <div>{kkkkk}</div>
}

Test.getInitialProps = () => {
  console.log('ooooooooooo')
  return {
    kkkkk: 'pppppp'
  }
}

export default Test;

spa遷移のときとserverで処理を分けたいときには、window.browserを使えばいい。

const Test = ({ kkkkk }) => {
return <div>{kkkkk}</div>
}

Test.getInitialProps = () => {
 if (window.browser) {
    console.log('window is not undefined')
    return 'bbbbb'
  }
  console.log('ooooooooooo')
  return {
    kkkkk: 'pppppp'
  }
}

export default Test;

getServerSideProps

↓公式
https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering

これ関数名的にserverSideのときに渡すpropsを生成っぽい感じなんだけど、実際は違う。

この関数を定義したページは、Linkで遷移させたとしても、必ずサーバーを経由するようになる。

この関数名はやめてほしいです。。!

なので、reduxのstoreの参照とかができないので、そこらへんの使い勝手が若干悪い気がしている。

まとめ

getInitialPropsは単純なSPA遷移ができて、storeを使えるので使っていきたい。

getServerSidePropsが推奨されているけど、必ずサーバー経由になっちゃってstore使えないのはちょっとやだねー。

なんか認識間違ってたら指摘してほしいーですー。

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

【Next.js】getStaticPathsで動的なルーティングをネストさせつつディレクトリ配下に任意のファイルを配置した

Next.jsで静的ホスティングの実装をしていました。

その際に、ネストした動的なルーティングに少しだけ詰まったので、備忘録を残したいと思います。

ちなみに、上記の詰まったことについては、stack overflowに助けられました。

参考:https://stackoverflow.com/questions/61732511/how-to-use-multiple-nested-dynamic-routes-with-getstaticpaths

Next.jsで静的ファイルをExportしたがディレクトリ名でファイルが作成された

以下の僕がGCSに対して静的ホスティングする際に、ディレクトリを動的なルーティングに出来るようにしていました。

https://qiita.com/arthur_foreign/items/a58bab8efa9498871356

最初は以下のようなディレクトリでした。

pages/
└──[directory]/
  └──index.js

ただ、yarn buildyarn exportのコマンドを実行して静的ファイルを出力すると、以下のようなファイルが出力されました。

out/
├── directory1.html
└── directory2.html

本来はディレクトリ単位で括って、その配下にindex.htmlが出力されている想定でしたが、どうも違うようでした。

これだと、directory配下にページを作りたいのに、同じ括りになりません。

getStaticPathsで動的なルーティングをネストさせることで想定通りのファイルを出力出来た

ディレクトリ名が直接ファイルとして出力されてしまっているので、動的ルーティングをネストさせて命名を固定すれば良さそうかと思ったので、以下2点の対応をしました。

  1. index.jsを動的ルーティングにした
  2. getStaticPathsでネストした動的ルーティングに対応した

ディレクトリ構成

pages/
└──[directory]/
  └──[page].js

getStaticPathsの動的ルーティングの実装

とりあえず、今回実装したのはメインのページだけだったので、page名はindex固定にしました。

export async function getStaticPaths() {
  const response = await fetch(
    process.env.HOST + '/api/pages'
  )
  const pageList = await response.json()
  const paths = pageList.map((page) => ({
    params: { directory: page.pagePath, page: 'index' },
  }))
  return { paths: paths, fallback: false }
}

これで静的ホスティングしているサイトとかに、ビルドした静的ファイルをデプロイすれば良いと思います。

GCPにはなりますが、Gloud Load Balancing + Cloud DNS + Cloud Storageで、リリースする手順を以下に方法を書いておきましたので、参考になりましたら幸いです。

参考:https://qiita.com/arthur_foreign/items/975794ba832aa742d459

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