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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Redux

Reduxは、JavaScriptアプリケーションの状態を管理するためのオープンソースライブラリです。ReactやAngularで一般的にユーザーインターフェイスの構築に利用されます。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

1321閲覧

ReduxのStateの更新の仕方がわからない

action_moto

総合スコア8

Redux

Reduxは、JavaScriptアプリケーションの状態を管理するためのオープンソースライブラリです。ReactやAngularで一般的にユーザーインターフェイスの構築に利用されます。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2020/02/08 05:51

編集2020/02/08 05:56

前提・実現したいこと

React+Reduxで、ファイルに関する情報を記録する簡単なアプリを書いています。
しかし、次のような配列とオブジェクト構造を持ったStateの一部を更新するreducerをどう書くのが良いのか分か、また、payloadとして何を渡すのが適切なのか悩んでいます。
教えていただけると有り難いです。宜しくお願い致します。

該当のソースコード

Reducer

jsx

1const initialState = [ 2 { 3 id: 1, 4 projectName: 'タナカのプロジェクト', 5 files: [ 6 { id: 1, 7 fileName: 'タナカのfileName1', 8 fileDesc: 'タナカのfileDesc1', 9 }, 10 { 11 id: 2, 12 fileName: 'タナカのfileName2', 13 fileDesc: 'タナカのfileDesc2', 14 }, 15 ], 16 }, 17 { 18 id:, 19 projectName: 'スズキのプロジェクト', 20 files: [ 21 { id: 1, 22 fileName: 'スズキのfileName1', 23 fileDesc: 'スズキのfileDesc1', 24 }, 25 { 26 id: 2, 27 fileName: 'スズキのfileName2', 28 fileDesc: 'スズキのfileDesc2',//例えばココの内容を変更したい 29 }, 30 ], 31 }, 32 33 34const updateFile = (state, payload) => { 35 //ここの書き方がわからないです。 36} 37 38//参考 ちなみにproject自体の更新に関しては以下のように記述しています。 39const updateProject = (state, payload) => { 40 return [ 41 ...state.filter( project => project.id !== payload.project.id), payload.project 42 ] 43} 44//参考以上 45 46export default createReducer(initialState, { 47 [UPDATE_FILE]: updateFile, 48})

ActionCreator

jsx

1 2export const updateFile = (?) => { 3 return { 4 type: UPDATE_FILE, 5 payload: { 6 //上に合わせてここをどう書けば良いでしょうか? 7 } 8 } 9} 10 11//参考 projectの更新 12export const updateFile = (project) => { 13 return { 14 type: UPDATE_PROJECT, 15 payload: { 16 project 17 } 18 } 19} 20//参考以上 21

Const

jsx

1export const UPDATE_FILE = 'UPDATE_FILE'; 2

ReducerUtil

jsx

1export const createReducer = (initialState, fnMap) => { 2 return (state = initialState, { type, payload }) => { 3 const handler = fnMap[type]; 4 return handler ? handler(state, payload) : state 5 } 6}

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんにちは。以下のような感じになるかと思います。

ご質問のコードにある //例えばココの内容を変更したいfileDesc を変更するためには、stateの配列の中から、指定されたproject id の要素の持つ files の中で、指定された file id に該当するオブジェクトの fileDesc を更新する必要があるので、ActionCreator のupdateFile の引数には、まず

  • projectId: number
  • fileId: number

の2点が必要です。さらに変更後の値を指定するために、

  • props: { fileName?: string, fileDesc?: string }

も受けつけるようにします。そうすると、以下のようになります。

typescript

1export const updateFile = (projectId: number, fileId: number, props: { fileName?: string, fileDesc?: string }) => { 2 return { 3 type: UPDATE_FILE, 4 payload: { 5 projectId, 6 fileId, 7 props 8 } 9 } 10}

たとえばご質問にある //例えばココの内容を変更したい の場合、 以下のように引数を渡します。

// プロジェクトIDが2の要素に含まれるfilesに含まれるファイルIDが2のオブジェクトのfileDescを"変更後の文字列" に変更する。 updateFile(2, 2, { fileDesc: '変更後の文字列' })

上記のようにActionCreatorの updateFile を作成した場合、Reducer の updateFile は、たとえば以下のように書けます。

typescript

1const updateFile = (state, payload) => { 2 return state.map(proj => { 3 if (proj.id === payload.projectId) { 4 const files = proj.files.map(file => { 5 if (file.id === payload.fileId) { 6 return { ...file, ...payload.props }; 7 } 8 return file; 9 }); 10 return { ...proj, files }; 11 } 12 return proj; 13 }) 14}

以上、参考になれば幸いです。

投稿2020/02/08 08:36

jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

action_moto

2020/02/09 04:21 編集

回答ありがとうございました。 typescriptが書けないのでjavascriptですが、正しく処理できるように書けました。 初めてのreduxのため、どこに処理を書いたらいいのか等迷いましたが、今回のことでスッキリと納得できました。 また、spread構文の理解が深まりました。 同じように、createFile,deleteFileを書いて行こうと思います。 ありがとうございました。
jun68ykt

2020/03/08 05:36 編集

どういたしまして。 Redux の state にしても、React.Component の this.state にしても、state を更新するロジックを書くときに、スプレッド構文および配列の map , filter はよく使います。書き方のコツとして、今回の場合でいえば、詳細部分のコードはさておき、 const updateFile = (state, payload) => { return state.map(proj => { // TODO 該当のproj だったら、新しいオブジェクトを作ってreturn return proj;   }) } といったような骨組みのコードを、まずは先に書いてしまってから、 TODO 部分を埋めていくという進め方で書くとよいかもしれません。ただし、createFile や deleteFile も同じパターンの return state.map(・・・ で書けるかというと、そうとも限りませんが。ともあれ > 今回のことでスッキリと納得できました。 とのことでよかったです????
action_moto

2020/02/09 09:31

ありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問