🐹

【今からReact #2】まずは「動かす」までやってみた!

に公開

はじめに

ピュアなJavaScriptではターミナルを使用して作業することはありませんでしたが、
Reactを勉強してみるとnpm installやらnpx create-react-appなど、ターミナルでの操作が前提のように話が始まります。

私は大学時代にC言語でトラウマを負ったタイプです。
黒い画面(=ターミナル)に長文のエラーに心が折れ、
いつしかプログラミング=難しい・苦手という意識が染みついてしまいました。

でも、JavaScriptはエラーが出ても割と優しくて、画面はなんとなく動くし、
HTMLに<script>タグを貼ってブラウザを開くだけでOK!
そんな手軽さが、JavaScriptを学び始めた頃はとてもありがたかったのです。

ステップアップのためにReactを学ぼうとしたとき——

「まずターミナルを開きます」

でたな、黒い画面。

一瞬、大学時代の苦い記憶がよみがえりました。
でも、いまやReactは世界中のフロントエンド開発で使われている定番ツール。
「それでも学びたい」という気持ちのほうが、あの恐怖を上回っていました

いまは、“わからないことを楽しむ”気持ちで、黒い画面に向き合えています。

Reactのプロジェクトの始め方や基本的なフォルダ構成、ファイルの中身についてはすでに多くの情報が出回っていますが、今回は自分用に整理した内容をまとめました。
同じようにReactをこれから学ぶ初心者の方にも、参考になる部分があれば嬉しいです。

なぜ、Reactではターミナルが必須になるのか?

冒頭でも少し触れたように、従来のJavaScriptはブラウザだけで完結するのでターミナルは不要でした。しかしReactはコンポーネント単位で画面を作るため、以下の仕組みが必要です。

  • React本体や関連ツールのインストール(npm)
  • JSX記法をブラウザが理解できるように変換する処理
  • 複数ファイルを1つにまとめるバンドル処理

このような環境構築や複雑な設定はターミナルを通して行うことが前提となっており、自動化されています。
そのおかげで「私のPCでは動くけど君のPCでは動かない」みたいな問題が減るというメリットも!

Reactのはじめかた

まずはターミナルでcdコマンドを使用して作業フォルダまで移動します。もしくはVSCodeなどのエディタ上から「フォルダを開く」で作業フォルダを開き、ターミナルを表示します。
私の場合、XAMPP(MAMP)を使用していたこともあり、作業フォルダはhtdocs内に作成しています。

CLI
cd /Applications/MAMP/htdocs

作業用フォルダまで移動したら、続けて以下のコマンドを実行します。

CLI
npx create-react-app (プロジェクト名)

このコマンドを実行すると、初期設定ファイルやライブラリが自動的にインストールされ、Reactプロジェクトの基本構成が生成されます。初回はやや時間がかかりますが、環境構築の多くが自動で行われるため、特別な設定をせずにすぐ開発を始めることができます。

npx(node package executer)は、Node.jsをインストールすると使えるようになるコマンド実行ツールです。npxコマンドはnpmで配布されているツールをその場で実行するためのコマンドです。(一時的にダウンロードして実行し、使い終わったら削除する)

つまり、npx create-react-appとすると、create-react-appというツールを毎回グローバルにインストールしなくても、最新版をネットから取ってきて使えるわけです。

npmとnpxの違い

npmは「パッケージを管理する」ためのツールで、パッケージ(ライブラリなど含む)をインストール、アップデート、削除したりします。さらに、package.jsonファイルに定義されたスクリプトを実行することもできます。

npxは「コマンドを一時的に実行する」ためのツールで、パッケージを事前にインストールしなくても、必要なタイミングでリモートから取得して実行できます。ローカル環境を汚さずに最新バージョンのツールを手軽に使えるのがメリットです。

ツール 役割
npm パッケージの管理や登録済みスクリプトの実行 npm install, npm start
npx パッケージのコマンドを一時的に実行 npx create-react-app

フォルダ構成について

Reactアプリを作ると、こんなフォルダたちが自動で作られます。

フォルダ名 中身と役割
node_modules Reactを動かすために必要な部品(ライブラリ)が保存されている。
public 一般公開されるファイルが保存されている。(例:index.html, favicon.icoなど)
src Reactのコードを書く場所。ここに自分のプログラムを入れていきます。

index.htmlについて

public/index.htmlは、Reactアプリの「土台」になります。

index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>

一見シンプルなHTMLですが、ポイントはこの一行👇

<div id="root"></div>

ここが、Reactアプリの「表示場所」。
Reactはこの<div id="root">に対して、画面に必要なHTML(正確にはJSX)を組み立てて差し込みます。

index.jsについて

Reactアプリの起点(スタート地点)になるのがsrc/index.jsです。

index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

Step1: 必要な部品を読み込む

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

まず、「react」という名前のパッケージから「React」という名前のオブジェクトをインポートします。これにより、useState()をはじめとしたフックや、createElement()などのReact APIを利用できるようになります。

次に、「react-dom」パッケージから、「ReactDOM」というオブジェクトをインポートします。これはReactコンポーネントをブラウザに表示(マウント)するための機能を担います。

最後に、同じ階層にある「App.js」(拡張子は省略可能)ファイルから、「App」というコンポーネントを読み込んでいます。
これにより、他のファイル(たとえばindex.js)で<App />のように記述して使えるようになります。

Step2: どこに表示するか決める

const root = ReactDOM.createRoot(document.getElementById('root'));

HTMLの<div id="root">を指定して、「ここにReactを表示するよ」と教えてます。

console.log()rootの中身を確認してみると、ReactDOMRootというオブジェクトが返されていることがわかります。次のStepにもある画面表示のためには、このオブジェクトの中にあるrenderメソッドを呼び出す必要があります。

Step3: 実際に表示する

root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

render()は、Reactコンポーネントをブラウザ上のDOMに描画します。
<App />は「表示したい中身」、<React.StrictMode>は開発中のみ有効なチェック機能。コードの問題点を早めに教えてくれます。意図しない副作用が起きそうなuseEffect()が2回呼び出されます。

App.jsについて

画面に表示したい内容は、App.jsというファイルに定義されています。

App.js
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;

Point1: 関数コンポーネントについて

Reactは画面に表示する内容を「コンポーネント」というパーツ単位で定義します。
いまは関数コンポーネントという方法が主流となっており、以下のように「普通のJavascript関数でUIを作る」イメージです。

function App() {
  return (
  // ここに必要な処理をJSXで記述

  );
}
  • Appという名前の関数を定義しています。
  • この関数は画面に表示したい内容をJSXという特別な記述で返します。
  • この関数に引数はなし。必要に応じてprops(プロパティ)という引数を使います。
  • Reactはこの関数が返したものを画面に表示します。

Point2: import, exportについて

exportは「作った関数や変数を他のファイルでも使えるようにする」ための仕組みです。

export default App

このように書くと、他のファイルからこのApp関数を呼び出すことができるようになります。

import App from './App';

別のファイルではimportを使ってこのように書くことで、App関数をそのまま使えるようになります。

defaultは、1つのファイルから「これがメインのものです」として1つだけエクスポートする時に使います。defaultにしたものは、インポートするときに名前を自由に決められます。

import Something from './App';

このように書くと、./App.js(拡張子は省略可能)でexport defaultされたものを読み込みます。つまり、App関数を読み込み、Somethingという名前で使用する、という意味になります。実際の使い方は以下のようなイメージです。

import Something from './App';

function Main() {
  return (
    <div>
      <Something />
    </div>
  );
}

Reactプロジェクトの実行

Reactプロジェクトを作成したら、実際に動かしてみましょう。
ターミナルでプロジェクトのフォルダに移動し、以下のコマンドを実行します。

npm start

実行すると自動的にブラウザが立ち上がり、Reactの初期画面が表示されます。
実際の動作は、npmがpackage.jsonファイルを読みに行き、そこで定義されたstartという名前のスクリプトreact-scripts startを実行しています。

package.json
{
  "scripts": {
    "start": "react-scripts start",
  },
}

なので、npmを使わない場合は、

npx react-scripts start

と同じ意味になります。

これがReactアプリのスタート画面です!

おわりに

今回はReactの初期設定を中心に、気になったポイントを自分なりに少し詳しくまとめてみました。
まだ実際の使い方や応用までは手をつけられていませんが、これから少しずつ学んでいくつもりです。

同じようにこれからReactを始める人の参考になれば嬉しいです。

Discussion