/react-reacthooks-lesson

Primary LanguageJavaScriptApache License 2.0Apache-2.0

基礎から学ぶ React/React Hooks

著書「基礎から学ぶ React/React Hooks(C&R研究所)」のサンプルコード集のページです。

各サンプルコードは一部を除きCodeSandbox上にあります。CodeSandbox画面右上にある「Fork」をクリックすると、内容をコピーした新しいSandBoxが作成され自由に編集できるようになります。

補足情報などもこのページで更新していく予定です。

CHAPTER1 Reactを始めるために必要なJavaScriptの知識

変数と宣言

タイトル ページ 補足
01-変数と宣言_スコープ p15
01-変数と宣言_ローカルスコープ p16
01-変数と宣言_const[ES2015] p18
01-変数と宣言_let[ES2015]-01 p18
01-変数と宣言_let[ES2015]-02 p18

データ型

タイトル ページ 補足
01-データ型_テンプレートリテラル[ES2015] p22

演算子

タイトル ページ 補足
01-演算子_比較演算子_等価演算子を利用するケース p26
01-演算子_比較演算子_大なり演算子と小なり演算子 p28
01-演算子_論理演算子 p29
01-演算子_短絡演算子 p30
01-演算子_条件(三項)演算子 p31

関数と宣言

タイトル ページ 補足
01-関数と宣言_functionを利用した関数宣言 p32
01-関数と宣言_無名関数で宣言(関数式) p33
01-関数と宣言_アロー関数式による定義 [ES2015] p33

引数

タイトル ページ 補足
01-引数 p36
01-引数_コールバック関数 p36
01-引数_デフォルト引数 [ES2015] p37
01-引数_可変長引数 [ES2015] p37
01-引数_引数の分割代入[ES2015]-01 p38
01-引数_引数の分割代入[ES2015]-02 p38

条件分岐とループ

タイトル ページ 補足
01-条件分岐とループ_if文 p39
01-条件分岐とループ_switch文-01 p41
01-条件分岐とループ_switch文-02 p42
01-条件分岐とループ_for文 p43
01-条件分岐とループ_for...in文 p43
01-条件分岐とループ_for...of文 [ES2015] p44
01-条件分岐とループ_while文 p45
01-条件分岐とループ_do...while文 p46

配列

タイトル ページ 補足
01-配列_配列要素へのアクセス_Array[index] p47
01-配列_配列であるかの判定_Array.isArray() p48
01-配列_配列から要素を検索_Array.indexOf() p48
01-配列_配列から要素を検索_Array.includes() [ES2016] p49
01-配列_配列要素の個数を取得_Array.length p50
01-配列_配列から文字列への変換_Array.toString() p50
01-配列_配列の連結_Array.concat(Array2,...) p51
01-配列_配列の連結_[...Array, ...Array2, ...Array3] p51
01-配列_配列の連結_Array.join() p52
01-配列_配列のソート_Array.sort()-文字列 p53
01-配列_配列のソート_Array.sort()-数値 p53
01-配列_配列のソート_元の配列を変更することなくArray.sort() p54
01-配列_配列のソート_Array.reverse() p55
01-配列_配列のソート_元の配列を変更することなくArray.reverse() p56
01-配列_配列要素の削除_Array.pop() p57
01-配列_配列要素の削除_Array.shift() p57
01-配列_配列要素の削除_Array.splice()-01 p58
01-配列_配列要素の削除_Array.splice()-02 p58
01-配列_配列要素の追加_Array.push() p59
01-配列_配列要素の追加_Array.unshift() p59
01-配列_配列のフラット化_Array.flat() [ES2019] p60
01-配列_分割代入 [ES2015] p61
01-配列_配列の高階関数-Array.forEach() p62
01-配列_配列の高階関数-Array.map() p63 コメントに表記ミスがありました
01-配列_配列の高階関数_Array.filter() p63
01-配列_配列の高階関数_Array.find()[ES2015] p64
01-配列_配列の高階関数_Array.findIndex()[ES2015] p65
01-配列_配列の高階関数_Array.every() p67
01-配列_配列の高階関数_Array.some() p68
01-配列_配列の高階関数_Array.reduce() p69

オブジェクト

タイトル ページ 補足
01-オブジェクト_オブジェクトとプロパティ p70
01-オブジェクト_プロパティへのアクセス p71
01-オブジェクト_プロパティの変更、追加、削除 p73
01-オブジェクト_スプレッド構文[ES2015]とレスト構文[ES2018] p74
01-オブジェクト_keyやvalue、プロパティの取り出し_Object.keys(obj) p75
01-オブジェクト_keyやvalue、プロパティの取り出し_Object.values(obj) [ES2017] p75
01-オブジェクト_keyやvalue、プロパティの取り出し_Object.entries(obj) [ES2017] p75
01-オブジェクト_オブジェクトを要素に持つ配列 p76

モジュール [ES2015]

タイトル ページ 補足
01-モジュール [ES2015]_名前付きexportとimport p78 動作確認のためサンプルコードをまとめた
01-モジュール [ES2015]_デフォルトexportとimport p80 動作確認のためサンプルコードをまとめた
01-モジュール [ES2015]_再エクスポート p82 動作確認のためサンプルコードをまとめた

非同期処理

タイトル ページ 補足
01-非同期処理_setTimeout() p83
01-非同期処理_Promise [ES2015]_クラス [ES2015]とビルドインオブジェクト p85
01-非同期処理_Promise [ES2015]_Promise.then()-01 p87
01-非同期処理_Promise [ES2015]_Promise.then()-02 p88
01-非同期処理_Promise [ES2015]_Promise.catch()-01 p88
01-非同期処理_Promise [ES2015]_Promise.catch()-02 p89
01-非同期処理_Promise [ES2015]_throwとエラー処理 p90
01-非同期処理_Promise [ES2015]_try...catch...finally文 p91
01-非同期処理_Promise [ES2015]_Promise.finally()[ES2018] p93
01-非同期処理_Promise [ES2015]_Promise.all() p94 動作確認のためPromiseオブジェクトを追加作成
01-非同期処理_Promise [ES2015]_Promise.race() p94 動作確認のためPromiseオブジェクトを追加作成
01-非同期処理_Async Function(async/await)[ES2017]_async p95
01-非同期処理_Async Function(async/await)[ES2017]_await-01 p96
01-非同期処理_Async Function(async/await)[ES2017]_await-02 p97

CHAPTER2 Reactの基礎知識

state

タイトル ページ 補足
02-LikeButtonコンポーネント p120

CHAPTER3 Reactを試してみよう

HTMLファイルでReactを試してみる

テキスト「いいね」とだけ表示されるLikeButtonコンポーネント

デスクトップ上などに空のindex.htmlファイルを作成し、以下のサンプルコードを貼り付けて動作確認にご利用下さい。

p129

<!DOCTYPE html>
<html>
  <head>
    <title>いいねボタン</title>
    <meta charset="UTF-8" />
    <script
      crossorigin
      src="https://unpkg.com/react@17/umd/react.development.js"
    ></script>
    <script
      crossorigin
      src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"
    ></script>
    <!-- babelを読み込むことで、JSXを使うことができるようになる -->
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
  </head>
  <body>
    <!-- Reactコンポーネントが表示されるDOMコンテナ -->
    <div id="likesButtonContainer"></div>

    <script type="text/babel">
      const LikeButton = () => {
        return "いいね";
      };

      const domContainer = document.querySelector("#likesButtonContainer");

      ReactDOM.render(<LikeButton />, domContainer);
    </script>
  </body>
</html>

クリックで、ボタン上のテキストの「いいね前」と「いいね済」がトグルするLikeButtonコンポーネント

デスクトップ上などに空のindex.htmlファイルを作成し、以下のサンプルコードを貼り付けて動作確認にご利用下さい。

p132

<!DOCTYPE html>
<html>
  <head>
    <title>いいねボタン</title>
    <meta charset="UTF-8" />
    <script
      crossorigin
      src="https://unpkg.com/react@17/umd/react.development.js"
    ></script>
    <script
      crossorigin
      src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"
    ></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
  </head>
  <body>
    <div id="likesButtonContainer"></div>

    <script type="text/babel">
      const LikeButton = () => {
        const [liked, setLiked] = React.useState(false);
        const toggleLiked = () => setLiked(!liked);

        return (
          <button className="likeButton" onClick={toggleLiked}>
            {liked ? 'いいね済' : 'いいね前'}
          </button>
        );
      };
      const domContainer = document.querySelector("#likesButtonContainer");

      ReactDOM.render(<LikeButton />, domContainer);
    </script>
  </body>
</html>

文字列の入力状態を保持するNameInputコンポーネント

デスクトップ上などに空のindex.htmlファイルを作成し、以下のサンプルコードを貼り付けて動作確認にご利用下さい。

p135

<!DOCTYPE html>
<html>
  <head>
    <title>NameInput</title>
    <meta charset="UTF-8" />
    <script
      src="https://unpkg.com/react@17/umd/react.development.js"
      crossorigin
    ></script>
    <script
      src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"
      crossorigin
    ></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
  </head>
  <body>
    <div id="nameInputContainer"></div>
    <script type="text/babel">
      const NameInput = () => {
        const [name, setName] = React.useState("〇〇");
        const handleOnChange = (event) => setName(event.target.value);

        return (
          <div>
            <input type="text" onChange={handleOnChange} />
            <p>こんにちは、{name}さん</p>
          </div>
        );
      };
      const domContainer = document.querySelector("#nameInputContainer");
      ReactDOM.render(<NameInput />, domContainer);
    </script>
  </body>
</html>

CodeSandboxでReactを試してみる

タイトル ページ 補足
03-Counter p143
03-筋トレカウンター p145

CHAPTER4 Reactの基本をマスターしよう

条件分岐で要素を出し分けよう

タイトル ページ 補足
04-if文_ログイン・ログアウトボタン p160
04-if文_即時関数を使ったテキスト出し分け p162
04-三項(条件)演算子 p163
04-論理積演算子 p164
04-論理和演算子 p165

繰り返し処理を書いてみよう

タイトル ページ 補足
04-mapで繰り返し処理 p168

イベント処理

タイトル ページ 補足
04-イベントハンドリング_onClick p170
04-イベントハンドリング_onChange p170

フォームを動かしてみよう

タイトル ページ 補足
04-テキスト入力フォーム p172 書籍中のサンプルコード一行目にimport React, { useState } from "react";が抜けていました
04-セレクトボックス p174
04-セレクトボックス(map処理) p176
04-ラジオボタン p178
04-ラジオボタン(map処理) p180
04-チェックボックス_複数のcheckedの状態を配列で管理 p183
04-チェックボックス_チェックボックスの状態を配列で管理(map処理) p185
04-チェックボックス_チェックボックスの状態をオブジェクトで管理 p188
04-チェックボックス_チェックボックスの状態をオブジェクトで管理(map処理) p191

CHAPTER5 React Hooksを基礎から理解する

useState

タイトル ページ 補足
05-useState_カウンターとテキスト入力フォーム p200
05-useState_カウンターとテキスト入力フォーム(コンポーネントを分割) p204

useEffect

タイトル ページ 補足
05-useEffect_カウンター(クリーンアップを必要としないコード例) p214
05-useEffect_カウンター(クリーンアップを必要とするコード例) p217

React.memo

タイトル ページ 補足
05-React.memoでコンポーネントをラップ p223
05-React.memoでコンポーネントをラップしない p226 動作確認のためコードを追加

useCallback

タイトル ページ 補足
05-useCallBackで関数をラップ p230
05-useCallBackで関数をラップしない p233

useMemo

タイトル ページ 補足
05-useMemoで関数の結果をラップ p237
05-useMemoで関数の結果をラップしない p241

useRef

タイトル ページ 補足
05-useRef_input要素をフォーカス p243
05-useRef_再レンダリング比較--useRefの場合 p245
05-useRef_再レンダリング比較--useStateの場合 p248

useContext

タイトル ページ 補足
05-useContext_ProviderとConsumer p253
05-useContext_Contextオブジェクトの値(string)を参照する p255
05-useContext_Contextオブジェクトの値(number)を参照する p260
05-useContext_子要素の出力props.children p264

カスタムフック

タイトル ページ 補足
05-useCounter_カウンターカスタムフック p266
05-useCounter_カウンターカスタムフック(分割) p270

CHAPTER6 TODOアプリを作成にチャレンジしよう

タイトル ページ 補足
06-axiosを利用してJSONPlaceholderからダミーデータを取得 p292 useEffect()の利用を追加した

TODOアプリを実装しよう

CodeSandbox上のサンプルコードは、ローカルに作成したモックサーバーを起動させていないとエラーが出るので注意して下さい。ローカルのモックサーバーの作成手順は次の通りです。

ローカルにモックサーバーを作成する

ローカル環境でJSON Serverを利用したモックサーバーを作成する方法は次の通りです。 デスクトップ上にlocalServerディレクトリを作成し、次の内容のdb.jsonファイルを格納します。

{
  "todos": [
    {
      "id": 1,
      "content": "Create React app をインストールする",
      "done": true
    },
    {
      "id": 2,
      "content": "JSON Server仮のAPIを作成する",
      "done": false
    },
    {
      "id": 3,
      "content": "Chakra UIをインストールする",
      "done": false
    }
  ]
}

JSON Server をインストールします。 (yarnがインストールされていることが前提です。)

# localServerディレクトリに移動
$ cd localServer

# 開発時のみ必要なライブラリなので、インストール時にdevオプションをつける
$ yarn add json-server --dev

モックサーバーを起動します。

# --port 3100(3100は任意の番号)でポート番号を指定
# http://localhost:3100/todos/
$ npx json-server --watch db.json --port 3100

モックサーバーが起動している状態で、CodeSandbox上のサンプルコードにアクセスして下さい。 ローカルに作成したモックサーバーを起動させていないとCodeSandbox上でエラーが出てTODOアプリは表示されません。 => ローカルにモックサーバーを作成する

TODOアプリサンプルコード

TODOアプリ作成の進捗①〜⑨ごとに分割しています。

タイトル ページ 補足
06-①モックサーバーと通信してTODOを取得する p295
06-②TODO一覧を状態(完了/未完了)別に表示させる p298
06-③タイトルとTODOリストをコンポーネント化 p302
06-④モックサーバーと通信するtodos.jsを作成 p306
06-⑤TODOを取得、追加、更新、削除するカスタムフックuseTodo()を作成 p309
06-⑥TODOをuseTodo()カスタムフックから取得する p312
06-⑦新規TODOの追加機能を実装する p315
06-⑦-2 TODO追加フォームコンポーネントを作成する p319
06-⑧TODOリストのアイテムに設置したボタンの機能実装 p322
06-⑨コンポーネントごとに別ファイルに切り分ける p328

CHAPTER7 Chakra UIでアプリにデザインを組み込む

Chakra UIって何?

Default Themeを確認しよう

タイトル ページ 補足
07-ChakraUI_Colors p335 動作確認のためコードを追加
07-ChakraUI_Typography p336 動作確認のためコードを追加
07-ChakraUI_Breakpoints p336,337 動作確認のためコードを追加
07-ChakraUI_Spacing p338 動作確認のためコードを追加
07-ChakraUI_Sizes p339 動作確認のためコードを追加
07-ChakraUI_BorderRadius p340 動作確認のためコードを追加

Style Propsを確認しよう

タイトル ページ 補足
07-ChakraUI_StylePropsTypography p340 動作確認のためコードを追加
07-ChakraUI_StylePropsMarginAndPadding p341 動作確認のためコードを追加
07-ChakraUI_StylePropsColorAndBackgroundColor p341 動作確認のためコードを追加
07-ChakraUI_StylePropsLayoutWidthAndHeight p343 動作確認のためコードを追加
07-ChakraUI_StylePropsFlexbox p344 動作確認のためコードを追加

Chakra UIでTODOアプリにデザインを組み込もう

Chakra UIをインストールしよう

p346

# Chakra UIをインストール
$ yarn add @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^4

p347

# chakra-ui iconをインストール
$ yarn add @chakra-ui/icons

CodeSandboxでChakra UIを利用したい場合は、CodeSandboxのDependenciesから、@chakra-ui/react、@emotion/react、@emotion/styled、@chakra-ui/icons、framer-motionを選択してインストールします。(CodeSandbox上のサンプルコードについては、すでにインストールされています。)

Chakra UI を触ってみる

モックサーバーが起動している状態で、CodeSandbox上のサンプルコードにアクセスして下さい。 ローカルに作成したモックサーバーを起動させていないとCodeSandbox上でエラーが出てTODOアプリは表示されません。 => ローカルにモックサーバーを作成する

タイトル ページ 補足
07-グローバルなテーマをカスタマイズしよう p349
07-Chakra UIのコンポーネントを利用しよう p356 CodeSandbox上のTODOアプリ完成形

TODOアプリソースコード

このリポジトリはCHAPTER6、CHAPTER7で紹介しているTODOアプリのソースコードです(完成形)。

ローカル環境での開発準備

jsonファイルを追加する

以下の内容でrootディレクトリ直下にdb.jsonを作成して下さい。

p286

{
  "todos": [
    {
      "id": 1,
      "content": "Create React app をインストールする",
      "done": true
    },
    {
      "id": 2,
      "content": "JSON Server仮のAPIを作成する",
      "done": false
    },
    {
      "id": 3,
      "content": "Chakra UIをインストールする",
      "done": false
    }
  ]
}

アプリ本体とモックサーバーを起動する

p287

# プロジェクトのrootへ移動(プロジェクト名は任意)
$ cd todo-app

$ yarn

# yarn start で todo-appを起動
# http://localhost:3000/
$ yarn start

# モックサーバーを起動
# --port 3100(3100は任意の番号)でポート番号を指定
# http://localhost:3100/todos/
$ npx json-server --watch db.json --port 3100

TODOアプリのイメージ

DESKTOP MOBILE
07-todoApp-deskTop 07-todoApp-mobile

動作環境

  • OS: macOS Mojave
  • ブラウザ: Google Chrome
  • エディタ: visual Studio Code3

各ツール等のバージョン

  • Node.js: v14.15.4
  • npm: 6.14.8
  • Yarn: 1.7.0
  • React: v17.0.2
  • Create React App v4.0.3
  • Chakra UI v1.6.4

免責事項

こちらのページで紹介しているサンプルコードはご自由にご活用下さい。ただし、サンプルコードの運用結果にまつわるあらゆる損害・障害については一切責任を負いませんのであらかじめご了承下さい。