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

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

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

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

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

Q&A

解決済

1回答

703閲覧

ReduxのReducerの3次元配列の更新が上手くいきません

退会済みユーザー

退会済みユーザー

総合スコア0

Redux

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

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

0グッド

0クリップ

投稿2020/01/29 15:05

編集2020/01/30 04:33

概要

現在、TypeScript+React+Redux+Go+gRPCを用いた個人開発を行っています。
そこで、gRPCで受け取った3次元配列のレスポンスをReducerに記述したいのですが、そこで今悩んでいます。
具体的には3次元配列の値をinitialStateにコピーする方法がわかりません。通常の一次元ならば記述できますので、配列を崩してReducerを複数作ることも考えたのですが、それはどうなのかと思い今悩んでいます。
自分なりに色々工夫してみましたが、解決せず。
どなたか解決方法のご教授お願い致します。

該当するコード

ProtocolBuffers

1// Protocol Buffers 2 3message ClearingHistoryRequest { 4 string token = 1; 5} 6message ClearingHistoryResponse { 7 bool status = 1; 8 enums.StatusCodes status_code = 2; 9 repeated Clearing ClearingHistory = 3; 10 11 message Clearing { 12 string date = 1; 13 Store store = 2; 14 Company company = 3; 15 repeated Product products = 4; 16 message Store { 17 uint64 id = 1; 18 string image = 2; 19 string address = 3; 20 } 21 message Company { 22 uint64 id = 1; 23 string name = 2; 24 } 25 message Product { 26 uint64 id = 1; 27 string name = 2; 28 uint32 price = 3; 29 } 30 } 31}

TypeScript

1// gRPCのリクエスト 2 3 /** 4 * 購入履歴 5 * 6 * @param {any} token 7 * @return 購入履歴 8 */ 9 public historyRequest = (token: any) => { 10 return new Promise(resolve => { 11 var ret: any 12 const req = new ClearingHistoryRequest() 13 req.setToken(token) 14 15 const client = new WebAppServiceClient("http://localhost:8080", {}) 16 client.clearingHistory(req, (err: any, res: any) => { 17 if (err || res === null) { 18 throw err 19 } 20 21 // 購入履歴の取得 22 const clearingHistories = res.getClearinghistoryList() 23 24 // 購入商品の取得 25 let products: any; 26 for (let i = 0; i < clearingHistories.length; i++) { 27 products = clearingHistories[i].getProductsList() 28 } 29 30 // 返却値の生成 31 let histories = new Array(clearingHistories.length) 32 for (let i = 0; i < clearingHistories.length; i++) { 33 histories[i] = { 34 date: clearingHistories[i].getDate(), 35 store: { 36 id: clearingHistories[i].getStore().getId(), 37 image: clearingHistories[i].getStore().getImage(), 38 address: clearingHistories[i].getStore().getAddress() 39 }, 40 company: { 41 id: clearingHistories[i].getCompany().getId(), 42 name: clearingHistories[i].getCompany().getName() 43 }, 44 product: { 45 id: products[0].getId(), 46 name: products[0].getName(), 47 price: products[0].getPrice() 48 } 49 } 50 } 51 52 resolve(histories) 53 }) 54 })

TypeScript

1// 購入履歴 2export interface iStore { 3 id: number, 4 image: string, 5 address: string 6} 7export interface iCompany { 8 id: number, 9 name: string 10} 11export interface iProduct { 12 id: number, 13 name: string, 14 price: number 15} 16 17export const getHistory = (token: any) => { 18 return async (dispatch: Dispatch<Action>) => { 19 try { 20 dispatch({ type: actionTypes.START_REQUEST }) 21 22 const histories: any = await User.historyRequest(token) 23 console.log(histories) 24 dispatch(setHistory(histories)) 25 26 dispatch({ type: actionTypes.COMPLETE_REQUEST }) 27 } catch (e) { 28 dispatch({ type: actionTypes.COMPLETE_REQUEST }) 29 dispatch(setNotification('error', 'エラーが発生しました!')) 30 } 31 } 32} 33export const setHistory = (histories: any) => ({ 34 type: actionTypes.SET_HISTORY, 35 payload: { 36 histories: histories 37 } 38}) 39

TypeScript

1// Reducer 2 3import * as actionTypes from '../utils/actionTypes' 4import * as actions from '../actions' 5 6type Actions = ( 7 | ReturnType<typeof actions.setHistory> 8) 9 10interface iState { 11 histories: [ 12 { 13 date: string, 14 store: actions.iStore, 15 company: actions.iCompany, 16 products: actions.iProduct[] 17 } 18 ] 19} 20 21const initialState: iState = { 22 histories: [ 23 { 24 date: "", 25 store: { 26 id: 0, 27 image: "", 28 address: "" 29 }, 30 company: { 31 id: 0, 32 name: "" 33 }, 34 products: [ 35 { 36 id: 0, 37 name: "", 38 price: 0 39 } 40 ] 41 } 42 ] 43} 44 45const HistoryReducer = (state: iState = initialState, action: Actions) => { 46 switch (action.type) { 47 case actionTypes.SET_HISTORY: 48 Object.assign({}, action.payload.histories) 49 console.log(state) 50 return Object.assign({}, state, { 51 state: action.payload.histories 52 }) 53 } 54 55 return state 56} 57 58export default HistoryReducer

追記

Reducerを下記の様に修正いたしました。

import * as actionTypes from '../utils/actionTypes' import * as actions from '../actions' type Actions = ( | ReturnType<typeof actions.setHistory> ) type History = { date: string, store: actions.iStore, company: actions.iCompany, products: actions.Product[] } interface iState { histories: History[] } const initialState: iState = { histories: [] } const HistoryReducer = (state: iState = initialState, action: Actions) => { switch (action.type) { case actionTypes.SET_HISTORY: return Object.assign({}, state, { state: action.payload.histories }) } return state } export default HistoryReducer

actionに記述していたinterface iProductも下記の様に修正いたしました。

// 購入履歴 export interface iStore { id: number, image: string, address: string } export interface iCompany { id: number, name: string } export type Product = { id: number, name: string, price: number }

gRPCのレスポンスは以下の様に返ってきます。

(4) [{…}, {…}, {…}, {…}] 0: date: "2020/01/29" store: {id: 1, image: "", address: "滋賀県彦根市"} company: {id: 1, name: "セブンイレブン"} product: id: 1 name: "コーラ" price: 150 __proto__: Object __proto__: Object 1: {date: "2020/01/29", store: {…}, company: {…}, product: {…}} 2: {date: "2020/01/29", store: {…}, company: {…}, product: {…}} 3: {date: "2020/01/29", store: {…}, company: {…}, product: {…}} length: 4

上記には記述されていませんが、case actionTypes.SET_HISTORYでreturnする前に

Object.assign({}, state, { state: action.payload.histories }) console.log(state)

をすると下記の様に表示されます。

{histories: Array(0)} histories: Array(0) length: 0

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

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

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

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

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

nerianighthawk

2020/01/30 02:08

「3次元配列」というのは、通常 [[[a, b, c], [d, e, f], [g, h, i]], [[j, k, l], [m, n]]] のような3重になっている配列のことを指しますが、質問のソースコードには見当たらないように思います。 どこのことを指していますか? また、現在のソースコードでどのような状況なのかを教えていただけると、質問に答えやすいです。 例:こういうエラーが出る、何も入っていない状態になる、等 よろしくお願いします。
退会済みユーザー

退会済みユーザー

2020/01/30 05:07 編集

gRPCのレスポンスが、histories[{date, store{}, company{}, product[{id, name, price},{id, name, price}, ...]}, {date, store{}, company{}, product[{id, name, price}, {id, name, price}, ...]}]の様に配列historiesの中に配列productが入っている為、3次元配列かと思っていました…。 追記いたしました!ご確認よろしくお願い致します! 他に必要な情報がございましたら、お手数をおかけしますがコメントして頂けると幸いです。
guest

回答1

0

ベストアンサー

Object.assign() 関数の引数の問題かと思います。

Object.assign(target, ...sources)target をコピー先、sources をコピー元、複数ある場合は順次上書きしていくという関数になります。

したがって、Object.assign({}, state, { histories: action.payload.histories }) と記載することによって、{} という空のオブジェクトに、まず現在の状態 state がコピーされ、次に{histories: action.payload.histories} が上書きされます。

khkhkh さんが記載している Object.assign({}, state, {state: action.payload.histories})state の中の state キーを更新しようとしていますが、iState の型に当てはまらないので処理が行われていないのかと思います。

投稿2020/01/30 05:06

nerianighthawk

総合スコア544

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

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

退会済みユーザー

退会済みユーザー

2020/01/30 05:36 編集

case actionTypes.SET_HISTORYでreturnする前に Object.assign({}, state.histories, action.payload.histories) console.log(initialState) と記述すると {histories: Array(0)} histories: Array(0) length: 0 の様に表示されました! 僕の理解ではこれで値が更新できるイメージなのですが、一体どこが間違っているのでしょうか…。ご教授いただけると幸いです。
nerianighthawk

2020/01/30 05:45

すみません、説明が不十分でした。 Reducer の戻り値で state の更新を行うはずなので、その場所での state の出力は更新前が出てしまうと思います(また、initialState はあくまで初期状態を表すものなので、この中身が書き換わるわけではありません)。 もし、console.log で出力したい場合は console.log(Object.assign({}, state, {histories: action.payload.histories})) 等で実行してみてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問