Skip to content

DNET_ReactSecondStep

nishi_74322014 edited this page Sep 11, 2026 · 1 revision

Reactのセカンド・ステップ

概要

create-react-appを使用した、React + Reduxの step by step。

手順1

色々悩んだが(と言うか、コチラの手順2の Redux 化に失敗したため)、
先ずは、以下の「Example: Todo List」のClass化版をやることに。

ココでは、Web備忘録の方をやってみた。

構成

─ src/
   ├─ App.js
   ├─ index.js
   ├┬ actions/
   │└─ Todo.js
   ├┬ components/
   │└─ Todo.js
   ├┬ containers/
   │└─ Todo.js
   ├┬ reducers/
   │└─ Todo.js
   └── createStore.js

サンプルの生成

>create-react-app react-redux-todo

インストール(手順1)

>npm install --save redux react-redux redux-logger

デバッグ設定(手順1)

デバッグ設定(Reactのファースト・ステップの「手順4」を参照)を行っておく。

実装(手順1)

以下を見ても明らかだが、

Entry Point, Component, Action, Reducer

と、複数のモジュールを行き来してシンドい。

Store作成(手順1)

  • createStore.jsを作成する。

  • ポイント

    • combineReducersをココで書いている。

    • applyMiddlewareで、
      Reduxの状態遷移をコンソール上に表示する
      redux-logger ミドルウェアを追加する。

Reducer作成(仮)(手順1)

  • reducers/Todo.jsを作成する。
    前述のStoreでimportしているReducerを仮で作成。

Reduxの組込(手順1)

  • index.jsに組込む。

    • createStoreして、storeを生成する。
    • AppタグをProviderタグでラップしつつstore属性にstoreを設定。
  • ここで一度 npm start コマンドを実行し動作することを確認。

Component作成(手順1)

  • components/Todo.jsを作成する。
  • そして、App.jsを修正してTodoを呼び出す。

Action作成(手順1)

  • actions/Todo.jsを作成する。

Reducer修正(手順1)

  • Reducer(仮)のreducers/Todo.jsにActionに対応した処理を実装する。

  • Actionから渡された値を「処理して」Componentに渡す。の処理の部分。

  • ポイント

    • 初期値はinitialStateで定義して使用する。
    • state は書き換えるのではなく新たなオブジェクトとするので、
      Object.assignでディープコピーし、それに値を設定し、戻り値とする。

Container作成(手順1)

  • containers/Todo.jsを作成する。

  • そして、App.jsを修正してTodoをComponentからContainerに切り替える。

  • ポイント:ここでconnectする。

Component修正(手順1)

  • components/Todo.jsで、propsのstateとfunctionを参照するように変更する。

実行(手順1)

  • Todoアプリを実行して動作確認する。

  • デバッグ実行(Reactのファースト・ステップの「手順4」を参照)すると、redux-logger ミドルウェアで、
    Redux の状態遷移はコンソール上に表示される。

サンプル(手順1)

https://github.com/OpenTouryoProject/SampleProgram/tree/master/Template/SPATemplate/react-redux-todo

手順2

「Example: Todo List」が動作したので、
先程失敗したコチラの手順2の Redux 化に再チャレンジ。

プロジェクトの準備(手順2)

  • コチラの手順2をコピーしてredux_appにリネーム。

  • 必要に応じて npmのインストール・コマンド(npmのコマンドの該当節を参照)で
    node_modulesを復元する必要がある。

    npm i
    

インストール(手順2)

>npm install --save redux react-redux redux-logger

デバッグ設定(手順2)

デバッグ設定(Reactのファースト・ステップの「手順4」を参照)を行っておく。

Component毎

実装(Component毎)

以下の辺りに注意しながら実装する。

  • redux-loggerを使用
  • createStoreの定義
  • Actionの分割
  • Reducerの書き方
  • Containerの使用
  • Componentからの参照方法

実行(Component毎)

  • またも動かない。

  • redux-loggerで、Reducersが動いていることは確認できるが、
    Component側が更新されない(State -> Componentの再実行がかかってない)。

  • 散々調べた挙げ句、原因は下で、

    • combineReducersを使うと以下のようにStoreが階層化されるため、

      {"Menu1":{"counter":0},"Menu2":{"counter":0}}
      
    • mapStateToPropsで、コレを考慮した設定にする必要があった。

      const mapStateToProps = state => {
        return {
          counter: state.Menu1.counter
        }
      }
  • Redux さん、もっと、

    • 使い易さと、
    • デバッグし易さを、

    考えて設計して欲しい感がある。

参考(Component毎)

Componentを跨ぐ

Componentを跨ぐという初歩的なことも良く解らないので、
ネットを調べて以下の参考ページを発見したのでやってみる。

実装(Componentを跨ぐ)

Menu1、Menu2のContainerを集約するContainer, Action, Reducerを、Menu12に集約。

  • Containerネストは不可能なので(当時そう思っていた)、Containerを集約する。
  • 従ってContainer以外にも、 Action, Reducerの集約を行う。
  • 親Containerから子Componentへは、propsを使用してstateとfunctionを渡す。

実行(Componentを跨ぐ)

無事、動作!

参考(Componentを跨ぐ)

サンプル(手順2)

https://github.com/OpenTouryoProject/SampleProgram/tree/master/Template/SPATemplate/redux_app

手順3

プロジェクトの準備(手順3)

  • コチラの手順3をコピーしてredux_templateにリネーム。

  • 必要に応じて npmのインストール・コマンド(npmのコマンドの該当節を参照)で
    node_modulesを復元する必要がある。

    npm i
    

デバッグ設定(手順3)

デバッグ設定(Reactのファースト・ステップの「手順4」を参照)を行っておく。

インストール(手順3)

  • 既知のモジュール

    >npm install --save redux react-redux redux-logger
    
  • ASP.NET Core React+Reduxテンプレートの新しいモジュール

    >npm install --save redux-thunk react-router-redux node-noop history domain-task
    

実装(手順3)

  • 手順1の手順を参考に、本丸の Redux 化に取り掛かる。
  • Counter、FetchDataの順にモジュールを追加していくと良い。

Store作成(手順3)

  • createStore.jsを作成する。

  • ポイント

    • combineReducersをココで書いている。
    • applyMiddlewareで、
      • Reduxの状態遷移をコンソール上に表示する redux-logger ミドルウェアを追加する。
      • 非同期処理を行うための thunk ミドルウェアを追加する。

Reducer作成(仮)(手順3)

  • 仮のReducerを作成
  • Counter、FetchDataの順にモジュールを追加

Reduxの組込(手順3)

  • index.jsに組込む。

    • createStoreして、storeを生成する。

    • AppContainerタグをProviderタグでラップしつつstore属性にstoreを設定。
      (以下のようなスニペットを発見したので、そのまま適用)

      ReactDOM.render(
        <Provider store={store}>
          <AppContainer />
        </Provider>, ・・・
  • また、routes.jsにページング処理のためのBrowserRouterを組込む。

    • BrowserRouterのインポート

      import { BrowserRouter as Router, Route } from 'react-router-dom'
    • LayoutタグをBrowserRouterのタグで囲む(なお、?はnull許容のもよう)

      <Router>
        <Layout>
          ・・・
          <Route path='/fetchdata/:startDateIndex?' component={ FetchData } />
        </Layout>
      </Router>
  • ここで一度 npm start コマンドを実行し動作することを確認。

Component作成(手順3)

作成済みなのでココでは何もしない。

Action作成(手順3)

  • Actionを作成

  • Counter、FetchDataの順にモジュールを追加

  • ポイント

    • Counterは通常通り。
    • FetchDataは
      • 非同期処理自体をReducerではなくココに定義。
      • 非同期処理の結果として、通常のActionを呼び出す。

Reducer修正(手順3)

  • Reducer(仮)のreducers/Counter、FetchData.jsにActionに対応した処理を実装する。

  • Actionから渡された値を「処理して」Componentに渡す。の処理の部分。

  • ポイント

    • 初期値はinitialStateで定義して使用する。
    • state は書き換えるのではなく新たなオブジェクトとするので、
      Object.assignでディープコピーし、それに値を設定し、戻り値とする。

Container作成(手順3)

  • containers/Counter、FetchData.jsを作成する。

  • そして、routes.jsを修正してCounter、FetchDataをComponentからContainerに切り替える。

  • ポイント:ここでconnectする。

    • Counterは通常通り。
    • FetchDataはActionに定義した非同期処理を呼び出す。

Component修正(手順3)

  • components/Counter、FetchData.jsで、propsのstateとfunctionを参照するように変更する。
  • なお、componentWillReceivePropsは無限ループ(stack overflow)防止コードが必要だった。

実行(手順3)

無事、動作!

サンプル(手順3)

参考(手順3)

移行メモ

  • 手順2「実行」で「mapDispatchToPropsで、コレを考慮した設定にする必要があった。」 とあるが、直後のコードは mapStateToProps の定義のため 「mapStateToProps」に修正した。
  • 手順1「Reducer修正」のポイントにあった空の箇条書きを除去した。
  • 同名の見出し(「インストール」「デバッグ設定」「実装」「実行」「サンプル」「参考」 「Store作成」「Reducer作成(仮)」「Reduxの組込」「Component作成」「Action作成」 「Reducer修正」「Container作成」「Component修正」「プロジェクトの準備」)が 複数あり GitHub Wiki でアンカが衝突するため、括弧で文脈を補って一意にした。
  • マイクロソフト系技術情報 Wiki(techinfoofmicrosofttech.osscons.jp)への URL リンクは、移行済みの ASP.NET Core React+Reduxテンプレート / ASP.NET Core に張り替えた。
  • PukiWiki のページ内アンカ(#xxxxxxxx)は GitHub Wiki では再現できないため、 同一ページ内のアンカは見出しから生成されるアンカに張り替え、 他ページのアンカを指すリンクは「〜(ページ名 の該当節を参照)」の形に置き換えた。

Tags: 移行, React, Redux, create-react-app, Store, Reducer, Container, redux-thunk, SPA

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally