34
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【React入門】忙しい人のためのReactチュートリアル

Last updated at Posted at 2022-03-07

はじめに

本記事はReactにこれから一歩を踏み出したいけどチュートリアルの難しい言葉理解してる時間はあまりない、という方に向けて、環境の構築からなんとなく画面が動くまでを解説します。
今回はReact + TypeScriptをベースに説明します。
これを読んでもっと知りたいと思った方は是非公式チュートリアルをお試しください。
https://ja.reactjs.org/tutorial/tutorial.html

目次

環境構築

Node

まずはパッケージ管理ツールであるnpmを利用するためにNodeをインストールします。

インストール

下のリンクからnodeのインストーラをダウンロードし、インストールを行ってください。
https://nodejs.org/ja/

Nodeとnpmのインストール確認

うまくいけばnodeとnpmのバージョンが表示されます。

$ node -v
v16.4.2
$ npm -v
7.18.1

Visual Studio Code

インストール

次に、統合開発環境のVisual Studio Codeをインストールします。
Atomなどでも問題ないですが、個人的に一番便利なのがVisual Studio Codeだと思っています。
https://code.visualstudio.com/download

日本語化

必要に応じて日本語化が可能です。

  1. Visual Studio Codeを開き、サイドバーから拡張機能のストアに移動します。
    スクリーンショット 2022-03-07 11.12.23.png
  2. 検索欄にJapaneseと打ち、Japanese Language Packをインストールします。
  3. Visual Studio Codeを再起動します。

Reactの導入

インストール

今回はcreate react appという、react公式が提供している環境の一括インストールを利用します。
Visual Studio Codeのターミナルで任意のディレクトリを開き下記のコマンドを実行してください。

$ npx create-react-app {任意のプロジェクト名} --template typescript
Need to install the following packages:
create-react-app
Ok to proceed? (y)

create-react-appをインストールしますか?と聞かれるのでYesと答えます。

確認

このようにいくつかのファイルが生成されていればインストール成功です。
スクリーンショット 2022-03-07 11.26.26.png
では、実際に動かしてみましょう。

$ npm start

インストールが成功したディレクトリに移動し、上記のコードを入力してください。
スクリーンショット 2022-03-07 11.30.31.png
ターミナルにこんな文字が表示されれば成功です。
Local: http://localhost:3000
ターミナルの3行目に記載されたこのURLをブラウザで開いてみてください。
スクリーンショット 2022-03-07 11.32.28.png
このような画面が表示されたと思います。
これで無事Reactの導入完了になります。

Reactの書き方

動かしてみる

まずは試しに今開いているサンプルページを少し触ってみましょう。
スクリーンショット 2022-03-07 11.39.10.png
{プロジェクト名}/src/App.tsxを開き、19行目の文字をHello World!にしてみましょう。
保存するとターミナルに文字が走り、自動的にページが更新されるはずです。
スクリーンショット 2022-03-07 11.40.50.png
このように、Reactではホットリロードという自動更新機能がデフォルトで導入されています。

.tsxファイル

次に.tsxというファイルについて簡単に説明します。
先程App.tsxという名前のファイルを編集しました。見慣れない拡張子だと思いますが、これは「React特有の書き方を利用したファイル」という意味になります。(JavaScriptの場合.jsxとなります)

特徴としては、関数の返り値にHTMLを記載するところが他の記法との大きな違いになります。
Reactの考えとしては「ロジック(JavaScript)とマークアップ(HTML)を別々に書く」従来の技術の分離ではなく、「ロジック(JavaScript)とマークアップ(HTML)を機能ごとにひとまとめにする」という関心の分離を採用しているため、このような記法になります。

コンポーネントとは

Reactについて調べていると、しばしば「コンポーネント」という単語を目にします。
コンポーネントとはロジックとマークアップを両方含む疎結合の部品を指します。
つまり、同じ機能を必要な場所で何度も再利用できるように機能ごとに分離して管理するという考え方です。

ページの余白等を決めるコンポーネント

ページに含まれるコンテンツのコンポーネント

コンテンツに含まれるアイテムコンポーネント

と言ったように、分離を行います。
イラスト2.png

実際に書いてみる

実際に動くコードを作ってみます。
まずは先程見たApp.tsxの中身をシンプルなものにしてみましょう。

function App() {
  return (
    <div className="App">
      <h1>Hello World!</h1>
    </div>
  );
}

export default App;

画面を見るとただ「Hello World!」と白い画面に表示されています。
先程話題に出たように、関数の返り値がHTMLになっていることが分かりやすく見えると思います。

変数の利用

このように書き換えてみましょう

function App() {
  const text: string = 'Hello World!';

  return (
    <div className="App">
      <h1>{text}</h1>
    </div>
  );
}

export default App;

画面を見ると何も変化がないことがわかると思います。
上記のように、変数をHTML内に入れられるのも.tsxの特徴です。

ルーティング

次はボタンを押したら画面が遷移されるようにしたいと思います。
まずは下記のルーティングライブラリをインストールします。

$ npm i react-router-dom

まずApp.tsxを下記のように変更します。

App.tsx
import { Link } from "react-router-dom";

function App() {
  const title: string = "Hello World!";

  return (
    <div className="App">
      <h1>{title}</h1>
      <Link to='/test'>
        ボタン
      </Link>
    </div>
  );
}

export default App;

{プロジェクト名}/src/test.tsxを作成し下記のコードを記述します。

test.tsx
function Test() {
  const title: string = "test";

  return (
    <div className="Test">
      <h1>{title}</h1>
    </div>
  );
}

export default Test;

その後、{プロジェクト名}/src/index.tsxを下記のように編集します。
ここでルーティングするURLやコンポーネントを指定しています。

index.tsx
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import Test from "./Test";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import reportWebVitals from "./reportWebVitals";

ReactDOM.render(
  <React.StrictMode>
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<App />} />
        <Route path="/test" element={<Test />} />
      </Routes>
    </BrowserRouter>
  </React.StrictMode>,
  document.getElementById("root")
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

画面に戻り、ボタンを押すと画面遷移することがわかると思います。

子コンポーネントとprops

今度はコンポーネント内でコンポーネントを呼び出してみましょう。
コンポーネントの説明で説明したように、コンポーネントは機能を分割したものになります。そのため、例えば画面コンポーネントの中にボタンコンポーネントを呼び出したいという場合は、コンポーネントをコンポーネントの中に呼ぶ、親子関係のような構造が出来上がります。

{プロジェクト名}/src/children/link.tsxを作成し下記のコードを記述します。

LinkButton.tsx
type LinkButtonProps = {
    text: string,
    link: string
}

function LinkButton(props: LinkButtonProps) {
  return (
    <div className="LinkButton">
      <Link to={props.link}>
        {props.text}
      </Link>
    </div>
  );
}

export default LinkButton;

この時、LinkButton.tsxtypeというものを宣言しています。
これは型宣言と呼ばれるもので、この型を利用した場合はオブジェクト型でstring型のtextstring型のlinkしかこの変数に入りませんという意味になります。TypeScriptはこうやって型を指定していくことで変な値の出入りを防いでいます。

次にApp.tsxを下記のように変更します。

App.tsx
import LinkButton from "./children/LinkButton";

function App() {
  const title: string = "Hello World!";

  return (
    <div className="App">
      <h1>{title}</h1>
      <LinkButton text="ボタン" link="/test" />
    </div>
  );
}

export default App;

画面を見るとルーティングの時と同じように動作しているのが分かります。
LinkButton.tsxは6行目のfunctionの引数に先程作成した型を指定しています。
このコンポーネント関数の引数こそpropsと呼ばれるもので、親コンポーネントから子コンポーネントへ値を受け渡すことが可能になります。
親側で書いた処理を子に渡すことで、子が不要な処理を抱え込まずに済むのがメリットです。
つまり、担当する機能を分割したままにコンポーネントを細かく増やすことができるのです。

React Hooksとstate

まずはこのように「増やす」ボタンを押したらnumが加算されるように書いてみます。

import LinkButton from "./children/LinkButton";

function App() {
  const title: string = "Hello World!";
  let num: number = 0;

  const increment = () => {
    num += 1;
    console.log(num);
  };

  return (
    <div className="App">
      <h1>{title}</h1>
      {num}回押しました。
      <LinkButton text="ボタン" link="/test" />
      <button type="button" onClick={increment}>増やす</button>
    </div>
  );
}

export default App;

スクリーンショット 2022-03-07 15.28.27.png

この書き方では画面の文字が変わらないことが分かります。
Reactでは、値の更新はとある方法で検知させないと画面に反映がされません。

ここで登場するのが状態管理、stateになります。
簡単に説明すると関数の状態を必要な時だけ更新することで、常に最新のHTMLを最低限の処理で返却するという機能です。
いくつか方法がありますが、今回はReact Hooksと呼ばれる機能を利用します。
下記のようにコードを修正してください。

import { useState } from "react";
import LinkButton from "./children/LinkButton";

function App() {
  const title: string = "Hello World!";
  const [num, setNum] = useState(0);

  const increment = () => {
    setNum(num + 1);
    console.log(num);
  };

  return (
    <div className="App">
      <h1>{title}</h1>
      {num}回押しました。
      <LinkButton text="ボタン" link="/test" />
      <button type="button" onClick={increment}>
        増やす
      </button>
    </div>
  );
}

export default App;

画面を見ると表示される数字が更新されていることが分かります。
このように、必要な時だけ画面レンダリングを行うことが可能になります。
スクリーンショット 2022-03-07 15.48.10.png
また、画面右側のconsoleの数字が画面に対して1低いことが気になった方もいるかと思います。
これはstateの更新は一瞬で済むものではなく、多少時間がかかってしまうため即時に変更後の値を取り出すのは難しいことを表しています。
この値が更新されたことを検知する方法もあるのですが、さらに多くのHooksを理解する必要があるため今回は省略します。
state管理に関するHooksについて紹介した記事があるのでそちらも参照していただけると理解が深まるかと思います。
https://qiita.com/r-terao/items/10d6fe6047f1d117b59a

おわりに

今回はReact + TypeScriptの環境構築から、ある程度コーディングすることが可能なレベルまでのチュートリアルをなるべく単語数少なめで紹介させていただきました。
Reactの良いところは、やはり関心事の分離という考え方にあると思います。
これを利用することで、例えば複数画面で再利用されるボタンコンポーネントを先に作ってから大人数で同時に利用して作業しても、処理部分を持っているのは呼び出す側のコンポーネントのためコンフリクトを起こしにくいのです。
このように大量にコンポーネントを生み出すような規模の大きい開発で大いに役立つReactというフレームワークを皆様一度利用してはいかがでしょうか?

34
25
1

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
34
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?