未熟学生エンジニアのブログ

TetsuFeの個人開発ブログ

TetsuFeはテツエフイー と読みます。FlutterやWeb周り全般、チーム開発について語るブログ

SPA・サーバレスハンズオン part2 一般的なwebページとReactアプリの構成を知る

シリーズ

Webページの主な構成要素

ブラウザでは主にhtml・cssjavascriptの3種類のファイルを扱う

  • HTML
    • ページの構造を決める。ブラウザ処理の起点になり、必要なcssやjsはここから読み込む
  • CSS
    • ページのレイアウト・色などを設定する
  • JavaScript(JS)
    • ページを書き換える、計算や通信などをするプログラムを実行する

Reactとは

Reactは、状況に応じて動的に書きかわるようなページを書きやすくするためのJavaScriptフレームワークです。使えばなんとなくわかります。

なぜReactを使うのか?

こちらの記事にまとめました。気になる方は読んでみてください。

なぜReact.jsを使うのか、jQueryやVue.jsとの違いをいまさら調べてみた - 未熟学生エンジニアのブログ

create-react-appのデフォルトコードについて

create-react-appをした場合、テンプレートコードが生成されます。

src、publicフォルダの中にあるコードが重要です。

$ tree src
src
├── App.css
├── App.js
├── App.test.js
├── index.css
├── index.js
├── logo.svg
└── serviceWorker.js
$ tree public
public
├── favicon.ico
├── index.html
└── manifest.json

起点はsrc/index.jsです。create-react-appで作ったreactアプリは、まずこのindex.jsが実行されます。

src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<App />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

ここで、以下の部分でAppというモジュールがインポートされています。要は、他のファイル(./App.js)にあるAppというモジュールをこのindex.jsでも利用できるようにしているということです。

import App from './App';

そして、以下の行でAppを利用して処理を走らせます。

ReactDOM.render(<App />, document.getElementById('root'));

これは、Appをrootというidを持つDOM要素の中に挿入するという意味になります。どういうことでしょうか?

実は、public/index.html というwebページのベースになるHTMLファイルがあります。

Appは、以下のテンプレートHTMLの中の <div id="root"></div><div id="root"></div>の間に挿入されます。

public/index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <!--
      manifest.json provides metadata used when your web app is installed on a
      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  </body>
</html>

Appが、<div id="root"></div>の間に挿入されることがわかりました。

では、Appとはなんなのか?その答えはsrc/App.jsにあります。なぜここに答えがあるとわかったと思いますか?なぜsrc/App.jsというファイル(答え)を探しあてることができたと思いますか?順をおって説明します。

React.jsを使ったプログラムは、基本的には単にjavascriptで書かれたプログラムです。javascriptがわかっていれば、答えにたどり着くことができます。

index.jsでのAppのインポートの方法を思い出してください。

src/index.js

import App from './App';

この構文は、「./App(./App.js)というファイルの中から、Appというモジュールをインポートする」という意味になります。

つまり、Appは./App.jsの中にあるということがわかり、Appの詳細を知りたければ./App.jsというファイルをみればいいということがわかります。これはReact.js特有の話ではなく、javascript一般に通じる話です。

ちなみに、./App.jsは、src/App.jsという意味です。(src/index.jsファイルの中では、.はsrcを意味します。ただし、これはファイルパスの一部として.が使われたときに限った話で、例えば先ほど出てきた以下のような例の場合は、.は別の意味になります。)

src/App.jsをみればいいということがわかったので、見ていきましょう。

src/App.js

import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

若干語弊はありますが、AppはApp()のことだったと考えてください。

ここで、App()は返り値として<div>で囲まれたオブジェクトを返しています。

実は、この<div>で囲まれた部分はreactのコード上ではjsのオブジェクトです。これを変換して、最終的にはHTMLの<div>タグと同じ意味のものになります。

ここで一度、ターミナルからサーバーを立ち上げて、ブラウザを見てみましょう。

$ npm start

以下のような画面が表示されるはずです。

f:id:swiftfe:20190430000840p:plain

ページを書き換えてみる

では、"Edit src/App.js and save to reload."を"Hello, my original app!"という文面に変えるには、どうしたらいいでしょうか?

f:id:swiftfe:20190430000932p:plain

先ほどのsrc/App.jsに、"Edit src/App.js and save to reload."という文字があるはずです。これを変えましょう。

src/App.js

        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>

以下のように変えます

        <p>
          Hello, my original app!
        </p>

編集して保存したら、ブラウザをみてみましょう。(実は、Reactを使うとブラウザのリロード操作がいりません!自動で更新されます。)

f:id:swiftfe:20190430001315p:plain

やりました!これでReactアプリを自分好みに編集していくことができるようになりました!

まとめ

  • javascriptの文法を読み解き、編集すべきファイルsrc/App.jsにたどり着けた
  • src/App.jsを編集すれば、自分のオリジナルアプリを書いていける
  • ベースとなるファイルindex.htmlに、Appというコンポーネントを挿入する形で要素を追加している

シリーズ