teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

ソース修正

2021/09/01 03:47

投稿

退会済みユーザー
answer CHANGED
@@ -31,4 +31,95 @@
31
31
  ```javascript
32
32
  const [i, j, k, value] = action.data;
33
33
  ```
34
- で一行で書けるよって。
34
+ で一行で書けるよって。
35
+
36
+
37
+
38
+ **もうひとつ補足:**
39
+
40
+ すでにベストアンサーにしてもろうた後やけど、もう一個お節介するわな。これだけネストの深いstateだと、[immutable-js](https://immutable-js.com/) を使うのもありかもしれへんよ。以下は、具体的には、こんな感じになるでしょうというイメージです。
41
+
42
+ - `yarn add immutable` して
43
+ - `initialState` を定義しているところで、
44
+ ```javascript
45
+ import { Map as ImmutableMap } from 'immutable'
46
+ ```
47
+ としておきます。`ImmutableMap` という別名でインポートするのは、念のため標準の`Map`と区別するためですわ。
48
+
49
+ - ほんで、`initialState`を以下のように、immutable-js のMapで作るんや。
50
+
51
+ ```javascript
52
+ const initialState = ImmutableMap({
53
+ TaskLogs : [
54
+ {
55
+ CreatedDate : "2020/81",
56
+ TaskGroupName: "SAMPLE_TITLE",
57
+ Tasks: [
58
+ {
59
+ Task: "FirstTask",
60
+ Date: {
61
+ "8/1": "11",
62
+ "8/2": "",
63
+ "8/3": "",
64
+ "8/4": "",
65
+ "8/5": "",
66
+ "8/6": "",
67
+ "8/7": "",
68
+ "8/8": "",
69
+ "8/9": "",
70
+ "8/10": "",
71
+ "8/11": "",
72
+ "8/12": "",
73
+ "8/14": ""
74
+ }
75
+ },
76
+ {
77
+ Task: "SecondTask",
78
+ Date: {
79
+ "8/1": "2",
80
+ "8/2": "",
81
+ "8/3": "",
82
+ "8/4": "", //例えば、ここの値だけを変更させたい
83
+ "8/5": "",
84
+ "8/6": "",
85
+ "8/7": "",
86
+ "8/8": "",
87
+ "8/9": "",
88
+ "8/10": "",
89
+ "8/11": "",
90
+ "8/12": "",
91
+ "8/14": ""
92
+ }
93
+ },
94
+ {
95
+ Task: "ThirdTask",
96
+ Date: {
97
+ "8/1": "300",
98
+ "8/2": "",
99
+ "8/3": "",
100
+ "8/4": "",
101
+ "8/5": "",
102
+ "8/6": "",
103
+ "8/7": "",
104
+ "8/8": "",
105
+ "8/9": "",
106
+ "8/10": "",
107
+ "8/11": "",
108
+ "8/12": "",
109
+ "8/14": ""
110
+ }
111
+ }
112
+ ]
113
+ },
114
+ ]
115
+ });
116
+ ```
117
+
118
+ こうやって、state全体をプレーンオブジェクトではなく、immutable-jsのマップにしておくと、`case UPDATE_TASKLOG:`んとこは、こないな感じ
119
+ ```javascript
120
+ case UPDATE_TASKLOG: {
121
+ const [i, j, k, value] = action.data;
122
+ return state.setIn( ['TaskLogs', i, 'Tasks', j, 'Date', k], value);
123
+ }
124
+ ```
125
+ にかなり簡単に書けると思います。ただこうすると、どのcaseでもstateをimmutable-jsのマップに変更したことでの修正をせなあきまへん。immutable-jsに慣れるための学習コストがそれなりにかかりますやろな。参考までに、 Redux のstateに immutable.jsを使うサンプルの記事ですねん。➡ [Redux stateにimmutable.jsを使う](https://qiita.com/sand/items/332bdc10638ef47673ba)

1

ソース修正

2021/09/01 03:47

投稿

退会済みユーザー
answer CHANGED
@@ -1,24 +1,34 @@
1
1
  いっぺんに作ろうとすると辛くなってくるので、深いところから順々に作っていき、段階ごとに一時的な変数に入れていけば確実やと思うで。こないな感じですわ。
2
2
  ```javascript
3
- let i = action.data[0]; //TaskLogs(配列)を指定する数値
3
+ const nextDate = {
4
- let j = action.data[1]; //Tasks(配列)を指定する数値
4
+ ...state.TaskLogs[i].Tasks[j].Date,
5
- let k = action.data[2]; //Date(オブジェクト)を指定するプロパティ名(例:k = "8/6")
5
+ [k]: value,
6
- let value = action.data[3]; //更新させたい値 (例:value="あああ", Date{"8/6": "あああ"}
6
+ };
7
7
 
8
- const nextDate = {
9
- ...state.TaskLogs[i].Tasks[j].Date,
8
+ const nextTasks = state.TaskLogs[i].Tasks.map((e, index) => ({
10
- [k]: value,
9
+ ...e,
10
+ Date: index === j ? nextDate : e.Date,
11
- };
11
+ }));
12
12
 
13
- const nextTasks = state.TaskLogs[i].Tasks.map((e, index) => ({
13
+ const nextTaskLogs = state.TaskLogs.map((e, index) => ({
14
- ...e,
14
+ ...e,
15
- Date: index === j ? nextDate : e.Date,
15
+ Tasks: index === i ? nextTasks : e.Tasks,
16
- }));
16
+ }));
17
17
 
18
- const nextTaskLogs = state.TaskLogs.map((e, index) => ({
19
- ...e,
20
- Tasks: index === i ? nextTasks : e.Tasks,
18
+ return { TaskLogs: nextTaskLogs };
21
- }));
19
+ ```
22
20
 
21
+ **補足:**
22
+
23
+ 本題とは関係あらへんのやけど、ちょっとお節介させてもらいますねん。以下の4行
24
+ ```javascript
23
- return { TaskLogs: nextTaskLogs };
25
+ let i = action.data[0]; //TaskLogs(配列)を指定する数値
26
+ let j = action.data[1]; //Tasks(配列)を指定する数値
27
+ let k = action.data[2]; //Date(オブジェクト)を指定するプロパティ名(例:k = "8/6")
28
+ let value = action.data[3]; //更新させたい値 (例:value="あああ", Date{"8/6": "あああ"})
24
- ```
29
+ ```
30
+ やけど、(1)分割代入を使う。(2) なるべくletではなくconstを使う。という2点でリファクタすると、こないな感じ:
31
+ ```javascript
32
+ const [i, j, k, value] = action.data;
33
+ ```
34
+ で一行で書けるよって。