質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.36%

  • React.js

    377questions

    A JavaScript library for building user interfaces

  • Redux

    49questions

React,Reduxでの変数の値を変更する適切なタイミングがわかりません。

解決済

回答 1

投稿 2017/11/27 14:25

  • 評価
  • クリップ 0
  • VIEW 42

cloudspider

score 55

 実際に作っているもの

4つのセレクトボックスを設置し(最初は1つだけ表示、残り3つは非表示)、
1個目のセレクトボックスが変更されたら、2個目が表示される。
2個目のセレクトボックスが変更されたら、3個目が表示される。
3個目のセレクトボックスが変更されたら、4個目が表示される。

というものを作っているのですが、1個目と2個目のセレクトボックスの選択肢は固定値なのですが、
3個目のセレクトボックスの選択肢は、1個目と2個目の選んだものによって選択肢を変えるようにしたいと考えています。

以下の画像のようなものです。
(ちなみに1個目の選択肢で「1」を選んだ場合は4は表示されないように実装しています in reducer)
また、3個目と4個目の選択肢は実装中なので、選択肢に変化はありません。
イメージ説明

 実装したいと思っていること

上述したような挙動を示すようにReduxを実装したいと思っています。
1個目と2個目の選んだものによって3個目の選択肢が決まる。
1,2,3で選んだものによって4個目の選択肢が決まります。

 試してみたこと

Reducerの中で、if文を書き1個目と2個目の選択肢が「○○」のとき、ローカルのリストfieldListに3個目のセレクトボックスの選択肢を入れます。
最後にstateであるfieldOptionList3に選択肢を入れます。
これによって3個目の選択肢を変更できると思いました。

    case actionTypes.UPDATE_3_OPTION:
        const fieldList = [] // ローカルのリストを作成
        if (state.FieldValue2 == 1) { 
            for (var i = 0; i < state.testList[0].length; i++) {
                fieldList.push(state.testList[0][i][0]) // initialStateの内のtestListからリストを作成
            }
        }
        return {
            ...state,
            fieldOptionList3: state.fieldOptionList3.concat(fieldList) //fieldOptionList3に入れる
        }


恐らく問題の原因だと思っているのは、これのreducerの実行のタイミングです。

 1つめのアプローチ

上述した4つのコンポーネント(redux-formをもちいたセレクトボックスのコンポーネント)を一つのクラスに入れて実装していました。
そして上述のreducerの実行のタイミングを、「このクラスのcomponentDidUpdate()の中」で実行しました。
すると、2個目のセレクトボックスの値を変更した直後に無限ループに入りました。
testListに同じ値(しかし正しい)が永遠にpushされ続けます。

 2つ目のアプローチ

1つめと同じことをrender()の前、componentWillUpdate()で実行してみました。
コレも同じで、2個目のセレクトボックスの値を変更した直後に無限ループに入りました。

 3つ目のアプローチ

この4つのセレクトボックスが一つのクラスに入っているので、このクラスのライフサイクルを指定してもタイミングがおかしくなるだけかなと思い、
各セレクトボックスを個別のクラスに分け、その個別のクラスの中でcomponentWillUpdate()を実装し、そのクラスを一つのクラスにまとめてみました。
これもまた、同じように2個目のセレクトボックスの値を変更した直後に無限ループに入りました。

 合っているのか間違っているのかわからない点

そもそもこういったものを作りたいと思った時にReducer内で場合分けをして、リストを作成しreturnするというのは正しいのでしょうか。Reducer内ではなく、Action内で行うものだったりするのでしょうか。

 その他

その他、「そもそもそういうのを実現したいのなら、全く別のシンプルな方法があるよ」などの意見があればそれも教えて頂けるとうれしいです。

よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

雑なコメントになってしまい申し訳ないですが、プルダウンメニューUIの状態を担当するreducerを作って、そこで各プルダウンメニューで選択されているものを管理してあげれば良いのではないでしょうか。

そして、各プルダウンメニューを表示するUI Component(またはそのComponentをラップするContainer)の方で、redux storeにconnectして、mapStateToPropsの中でごにょごにょすれば良いのではないかと思います。

function mapStateToProps(state, ownProps) {
  return {
    optionsForXxx: getOptions(state.selectMenuUi)
  }
}


上のoptionsForXxxというのが1番目、2番めのプルダウンメニューの選択肢によって表示するオプションリストが変動するプルダウンメニューのオプションリストだとして、UIの状態を管理するreducerだとして、state.selectMenuUiというのが、各プルダウンメニューの選択されている値を管理するreducer。そして、getOptionsという関数がいやゆるselectorと呼ばれるもので、現在のstateに応じた値を計算なり判断なりして決める役割を持つもの。(reselectorライブラリというのがあるので、それを使うと良いかもしれません。)

reducerの方ではあくまで現在、選択されている各プルダウンメニューの識別値のみを管理させて、実際に表示するオプションのリストはselector、またはコンポーネントの方で依存しているプルダウンメニュ側で選択されているオプションに応じたものを出してあげれば良いのではないかと思います。

投稿 2017/11/27 15:45

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.36%

関連した質問

同じタグがついた質問を見る

  • React.js

    377questions

    A JavaScript library for building user interfaces

  • Redux

    49questions