Python×Django+RestFramework×ReactでWebアプリケーション➃ JavaScript・・・を踏まえてReact その➊ 静的なコンポーネント
1.React概要
JavaScriptは前回見ていただいたように、HTML要素を対象に動的にサイトを動かすようなコードを書いていく感じでした。
ではReactの特徴は何でしょうか。
(1) ReactのみでWebページを作成可能
厳密に言うと、CSSについてはやり方は様々なので一概に言えませんが、基本JSXといってJavaScriptのコード内にタグを書きます。
もちろんJavaScriptの処理も一緒に書けます。
(2) コンポーネントを組み合わせる
そうして作成したコンポーネントという各部品や処理を繋げていくことで、一つの頁を作成しています。
また、React自体がクラスコンポーネントという書き方をせずに記載できるようになったため、コードの可読性も良いため、保守性にも優れているといえます。
(3) 仮想DOMによるレスポンス良化
DOMはHTML・CSS・JavaScriptなどをまとめたWebページを表示するための構造のようなイメージです。
変更が発生した場合に、再度HTML・CSS・JavaScriptを解釈しDOMを再構成するためJavaScriptが多様された場合等、Webページのレスポンスが重くなってしまう問題がありました。ReactはDOMをいちいち全て更新せず、変更があった部分だけが更新されるためレスポンスが良いのが特徴です。
2.実際にReactを書いてみよう
実際に書いてみた方がイメージが掴めると思うので、やっていきます。
(1) CodeSandboxでCreatSandboxを選択
まずはCreate Sandboxをぽちっとします。
(2) Reactを選択する
次にReactを選択します。なお、Code SandboxだとWebページ上で作成→稼働までできてしまいます。
自分のPC上で行う場合は、Node.jsをまずはインストールして、ターミナルやコマンドプロンプトで「npx creat-react-app プロジェクト名」と入力すると、必要なファイルを該当フォルダにインストールされる流れとなります。
Reactを選択すると、以下のような状態で画面が開いていると思います。
(3) フォルダ・ファイル構成と簡単に仕組みを理解する
フォルダ・ファイル構成を見てみましょう。
publicというフォルダに、index.htmlファイルがあります。srcというフォルダ内にApp.js、index.js、styles.cssという3つのファイルがあり、両フォルダの外にpackace.jsonというファイルがあります。
まずは、App.jsファイルの中身を見てみましょう。
App.js
import "./styles.css";
export default function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
順番に見ていくと、まず同じフォルダ内のstyles.cssファイルをインポートしています。インポートはApp.jsファイル内で、利用するためにしています。
次にexport default function App() {}という記載がありますが、これはAppという関数コンポーネントを他のコンポーネントなどで読み込めるようにエクスポートしているものです。
では、関数内でどのような処理をしているかreturnの後を見ていくと、なんとHTMLタグが書かれています。
これは、先ほど書いたJSXというもので、React内にWebページの要素を記載するための記法です。
いずれにしても、この内容をAppという関数ファンクションで作成して、他のファイルで読み込めるようにしているんだな、と理解すればOKかと思います。
次にindex.jsファイルを見てみます。
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import App from "./App";
const rootElement = document.getElementById("root");
ReactDOM.render(
<StrictMode>
<App />
</StrictMode>,
rootElement
);
StrictModeはコードの問題点を確認するためのものなので、あまり気にせずOKですし、これから書いていくときに必須となるものではありません。
そこを除いて見ていくと、まずReactDomを、react-domからインポートしています。これは、コードの中で出てくるReactDom.render()という処理をするためのものです。
renderしている内容の第一引数に、<APP />が第2引数にrootElementが渡されています。
最後にindex.htmlファイルを見てみましょう。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<title>React App</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
</body>
</html>
HTMLのコメントである<!-- -->で囲まれた部分を除くと、上記のような記載となります。
注目してもらいたいのは、bodyタグの部分、nosctiptはWebページ上に表れていませんし、id属性がrootと記載されている部分も中身は空です。
つまり、簡単に書くと、以下のような仕組みとなっています。
(4) はじめの一歩 ~コードを書いてみる~
まずは、App.jsの記載を修正してみましょう。App.jsの以下の部分を書き変えてみてください。
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
私は以下のように書き変えました。
<h1>はじめの一歩</h1>
<h2>これはReactとの初めての遭遇です</h2>
すると、以下のように表示が変わるかと思います。
では実際にお買い物リストを作成していきます。
3.お買い物リストをReactで作成する
(1) まずは骨組みを作る
まずは骨組みとして、一旦動的な処理は考えずレイアウトだけ構築していきます。
(2) 各パーツをコンポーネントとして別ファイルに作成する
今回も入力エリア、未購入エリア、購入済エリアの3つに分けて作成していきたいと思います。
まずは、componentsというフォルダをsrcフォルダの配下に作成します。
次に、componentsフォルダ配下に以下3つのjsファイルを作成します。
・ InputArea.js
・ HaveNotBuy.js
・HaveBuy.js
ご想像のとおり、入力・未購入・購入の3つのコンポーネントです。
まずは、入力欄から作成します。
InputArea.js
基本、JavaScriptバージョンのclass属性がinput-areaの部分から引っ張ってくればOKですが、JSX記法でclass属性は「className」と記載する必要がありますので留意ください。
export default function InputArea() {
return (
<>
<div className="input-area">
<h2 id="header">入力欄</h2>
<input id="input" type="text" placeholder="買うものを入力" />
<button id="add">追加</button>
</div>
</>
);
}
HaveNotBuy.js
未購入エリアもclass属性にだけ注意して、JavaScriptバージョンのindex.htmlファイルから拝借する感じで大丈夫です。
export default function HaveNotBuy() {
return (
<div className="have-not-buy">
<h2 className="header">未購入</h2>
<ul>
<div id="need-to-buy"></div>
</ul>
</div>
);
}
HaveBuy.js
購入済エリアも同様です。
export default function HaveBuy() {
return (
<div className="have-buy">
<h2 className="header">購入済</h2>
<ul>
<div id="buy-already"></div>
</ul>
</div>
);
}
(2) 複数のコンポーネントをどう組み合わせるか
componentsの各パーツができたところで、最後にApp.jsに以下のように記載します。
まずは、各コンポーネントをimportします。
そして、各コンポーネントを並べます。
App.js
import "./styles.css";
import InputArea from "./components/InputArea";
import HaveNotBuy from "./components/HaveNotBuy";
import HaveBuy from "./components/HaveBuy";
export default function App() {
return (
<div className="App">
<h1>お買い物リスト</h1>
<InputArea />
<HaveNotBuy />
<HaveBuy />
</div>
);
}
最後に、styles.cssファイルにJavaScriptバージョンで使用したものと、同じ内容を貼り付ければ・・・静的な部分は完成です。
Styles.css
.title {
color: #555;
font-family: sans-serif;
}
#header {
font-family: sans-serif;
margin: 10px;
}
.input-area {
background-color: lightblue;
width: 800px;
height: 110px;
margin-left: 15px;
padding-top: 1px;
padding-bottom: 5px;
padding-left: 20px;
border-radius: 10px;
font-family: Arial;
}
h1 {
margin: 5px;
padding: 5px;
}
input {
border-radius: 4px;
border: none;
padding: 5px 20px;
outline: none;
}
button {
border-radius: 4px;
border: none;
padding: 5px 15px;
outline: none;
padding: 5px;
margin: 5px;
}
button:hover {
background-color: #555;
color: aliceblue;
}
.have-not-buy {
background-color: lightsalmon;
width: 800px;
margin: 15px;
padding-top: 1px;
padding-bottom: 15px;
padding-left: 20px;
border-radius: 10px;
font-family: Arial;
}
.have-buy {
background-color: darkgray;
width: 800px;
margin: 15px;
padding-top: 5px;
padding-bottom: 15px;
padding-left: 20px;
border-radius: 10px;
font-family: Arial;
}
(3) 表示を確認する
Browserエリアに以下のとおり表示されていれば完成です。
4.まとめ
長くなるので、動的な部分は次回の書いていきたいと思います。
ポイントは以下3点。
➊ JSX記法でHTMLのようにタグが記載できる
➋ class属性はclassNameとキャメルケースで記載する必要あり
➌コンポーネントは他のコンポーネントでインポートして利用可能