LoginSignup
0
2

More than 3 years have passed since last update.

素人基盤エンジニアがDockerでDjango REST Frameworkとreactを触るシリーズ③:reactの導入

Last updated at Posted at 2021-03-28

素人基盤エンジニアがDockerでDjango REST Frameworkとreactを触るシリーズ②:Django REST Frameworkのつづき。
①からみたい場合はこちら。素人基盤エンジニアがDockerでDjango REST Frameworkとreactを触るシリーズ①:Djangoの導入

reactの導入

最終的には、S3上にreactのアプリを配置してCloudFront経由で表示させたいが、構築/テストまでは同じEC2上でreactとdocker上のDjango REST frameworkを動作させて連携させることとする。
動作が確認出来たら、ビルドしS3に移行する。

node.jsの導入

reactのビルド環境として、node.jsが必要なので、下記手順に従いインストールする。
https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v2/developer-guide/setting-up-node-on-ec2-instance.html

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
. ~/.nvm/nvm.sh
nvm install node
node -e "console.log('Running Node.js ' + process.version)"

Running Node.js v15.12.0
↑のような形でバージョンが表示されたらインストールは完了。

create-react-app

今回は、reactアプリを簡単に作成することができるツールであるcreate-react-appを利用する。
(本格的にreactアプリを作成したい場合は自分で一から作成したほうが良いと思うが、今回はあくまでreactとDjango REST Frameworkを利用してとりあえず動くものを作るというところを目標とする。)
djangoのためのファイル群をbackendというディレクトリに作成したので、一旦/home/ec2-userまで戻り、下記コマンドを実行する。

cd /home/ec2-user
npm install -g yarn
yarn global add create-react-app
create-react-app frontend

しばらくすると、frontendというディレクトリが作成され、下記のような構成になっているはず。

frontend
∟node_modules
 ∟パッケージ多数
∟package.json
∟public
 ∟favicon.ico
 ∟index.html
 ∟logo192.png
 ∟logo512.png
 ∟manifest.json
 ∟robots.txt
∟README.md
∟src
 ∟App.css
 ∟App.test.js
 ∟index.js
 ∟reportWebVitals.js
 ∟App.js
 ∟index.css
 ∟logo.svg
 ∟setupTests.js
∟yarn.lock

まずはデフォルトの状態で、reactアプリを起動させてみる。

cd frontend
yarn start

http://<ip-address>:3000
にアクセスする。
DRF011.png
reactアプリが動作していることがわかる。
ctrl+Cで一旦終了し、下記ソースを修正してみる。

public/index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <link href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" rel="stylesheet">
    <title>ReactSampleApp</title>
  </head>
  <body>
    <h1 class="title">ToDo Apps(React+DjangoRestFramework)</h1>
    <div id="root"></div>
  </body>
</html>
src/App.js
import React, { Component } from 'react';
import axios from 'axios';

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            todos: [],
            hostname: ""
        };
    }

    componentDidMount() {
        this.getTodos();
        this.getHostname();
    }

    getTodos() {
        axios
            .get('http://<ip-address>:8000/api/todos/')
            .then(res => {
                this.setState({ todos: res.data });
            })
            .catch(err => {
                console.log(err);
            });
    }

    getHostname() {
        axios
            .get('http://<ip-address>:8000/api/hostname/')
            .then(res => {
                this.setState({ hostname: res.data });
            })
            .catch(err => {
                console.log(err);
            });
    }

    render() {
        return (
            <div>
                {this.state.todos.map(item => (
                    <div key={item.id}>
                        <h2>{item.title}</h2>
                        <p className="item_body">{item.body}</p>
                    </div>
                ))}

                <div className="box30">
                    <div className="box-title">HOSTNAME</div>
                    <p>{this.state.hostname.hostname}</p>
                </div>
            </div>
        );
    }
}

export default App;

<ip-address>の部分を、EC2のIPアドレスにすることを忘れないように注意。
ここは、CloudFrontでの構成に移行すればIPアドレスを書かなくてもよくなる。

src/index.css
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
    monospace;
}

h1.title {
  font-family: 'Segoe Print',sans-serif;
  padding: 0.5em;
  color: #494949;/*文字色*/
  background: #fffaf4;/*背景色*/
  border-left: solid 5px #ffaf58;/*左線(実線 太さ 色)*/
}

.box30 {
    margin: 0 auto 0 20px;
    width: 300px;
    background: #f1f1f1;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.22);
}
.box30 .box-title {
    font-size: 1.2em;
    background: #5fc2f5;
    padding: 4px;
    text-align: center;
    color: #FFF;
    font-weight: bold;
    letter-spacing: 0.05em;
}
.box30 p {
    text-align: center;
    padding: 15px 20px;
    margin: 0 0;
}

h2 {
  position: relative;
  padding: 8px 15px;
  margin-left: 40px;
  background: #def3ff;
  border-radius: 20px;
}

h2:before {
  font-family: "Font Awesome 5 Free";
  content: "\f111";
  position: absolute;
  font-size: 15px;
  left: -40px;
  bottom: 0;
  color: #def3ff;
}

h2:after {
  font-family: "Font Awesome 5 Free";
  content: "\f111";
  position: absolute;
  font-size: 23px;
  left: -23px;
  bottom: 0;
  color: #def3ff;
}

p.item_body {
  font-family: 'Mv Boli',sans-serif;
  margin-left: 80px;
}

ソース内で、axiosというパッケージを利用しているので、frontendディレクトリで下記コマンドを利用してパッケージを追加しておく。

yarn add axios

また、Django側の設定も、別サイトからのクロスオリジンアクセスがあるため、下記のように書き換える。

backend/todo_project/settings.py
MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

CORS_ORIGIN_ALLOW_ALL = True

一行目のcorsheaders~と最後のCORS_ORIGIN_ALLOW_ALLを追加。

docker-compose upでdbとdjangoのコンテナを起動する。
(この後reactも起動したいのでバックエンドで起動する。)

cd backend
docker-compose up &

コンテナを起動させたまま、reactを起動。

cd ../frontend
yarn start

http://<ip-address>:3000/
にアクセスしてみる。
DRF012.png

無事、todoとhostnameが表示されていることがわかる。
次回は、今回構築したreactアプリをビルドしS3へ配置して最終系であるCloudfrontの形に変更する。

つづく

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2