回答編集履歴

10

テキスト修正

2019/09/15 19:36

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -80,13 +80,13 @@
80
80
 
81
81
 
82
82
 
83
- 個人的には、上記に箇条書きで書かれている、 presentational components と container components それぞれの特徴を、満たす条件ととらえてすべてを厳密に守ろうとすると、融通がきかなくなってしまいがち、という所感を持っています。上記の記事は、はじめ2015年に書かれたものですが、その後、冒頭に`Update from 2019` として追記があり、追記の最後に
83
+ 個人的には、上記に箇条書きで書かれている、 presentational components と container components それぞれの特徴を、満たす条件ととらえてすべてを厳密に守ろうとすると、融通がきかなくなってしまいがち、という所感を持っています。(実際、上記の記事は、はじめ2015年に書かれたものですが、その後、冒頭に`Update from 2019` として追記があり、追記の最後に
84
84
 
85
85
  > This text is left intact for historical reasons but don’t take it too seriously.
86
86
 
87
87
 
88
88
 
89
- とDan氏自身が書いていることから、「厳密に守ろうとすると、融通がきかなくなってしいがち」という所感も間違いではなかったかなという印象です。
89
+ とDan氏自身が書いています。
90
90
 
91
91
 
92
92
 

9

テキスト修正

2019/09/15 19:36

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -146,7 +146,7 @@
146
146
 
147
147
 
148
148
 
149
- ということになるわけですが、これを「そんなことを認めたら、収がつかなくなるので認められない」と考えるか、「redux に connectさせるかどうかに縛られるよりも、 containerは大きな容れ物で、 component は containerに詰められる部品と考えたほうが、開発作業上のメリットが大きい」という考えを採用するかは、プロジェクトによって違っていました。
149
+ ということになるわけですが、これを「そんなことを認めたら、収がつかなくなるので認められない」と考えるか、「redux に connectさせるかどうかに縛られるよりも、 containerは大きな容れ物で、 component は containerに詰められる部品と考えたほうが、開発作業上のメリットが大きい」という考えを採用するかは、プロジェクトによって違っていました。
150
150
 
151
151
 
152
152
 

8

テキスト修正

2019/09/15 17:04

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -86,7 +86,7 @@
86
86
 
87
87
 
88
88
 
89
- とDan氏自身が書いています。
89
+ とDan氏自身が書いていることから、「厳密に守ろうとすると、融通がきかなくなってしいがち」という所感も間違いではなかったかなという印象です。
90
90
 
91
91
 
92
92
 

7

テキスト修正

2019/09/15 16:43

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -80,11 +80,17 @@
80
80
 
81
81
 
82
82
 
83
- 個人的には、上記に箇条書きで書かれている、 presentational components と container components それぞれの特徴を、満たす条件ととらえてすべてを厳密に守ろうとすると、融通がきかなくなってしまいがち、という所感を持っています。
84
-
85
-
86
-
87
- 上記の記事を、ご質問に挙げられているコードに適用してみると、container components の特徴の中には、
83
+ 個人的には、上記に箇条書きで書かれている、 presentational components と container components それぞれの特徴を、満たす条件ととらえてすべてを厳密に守ろうとすると、融通がきかなくなってしまいがち、という所感を持っています。上記の記事は、はじめ2015年に書かれたものですが、その後、冒頭に`Update from 2019` として追記があり、追記の最後に
84
+
85
+ > This text is left intact for historical reasons but don’t take it too seriously.
86
+
87
+
88
+
89
+ とDan氏自身が書いています。
90
+
91
+
92
+
93
+ とはいえ、今でもひとつの目安にはなるので、上記の記事を、ご質問に挙げられているコードに適用してみると、container components の特徴の中には、
88
94
 
89
95
 
90
96
 

6

テキスト修正

2019/09/15 16:41

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -116,7 +116,7 @@
116
116
 
117
117
 
118
118
 
119
- は、 container とする。つまり App から直接 import されるものは、大きな部品と考えて差し支えないはずだから、container とす
119
+ は、 container とする。これの根拠となるのは、「App から直接 import されるものは、ざっくり言って、大きな部品と考えて差し支えないからいう考え方です。
120
120
 
121
121
 
122
122
 

5

テキスト修正

2019/09/15 16:22

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -136,7 +136,7 @@
136
136
 
137
137
 
138
138
 
139
- - container なのか (presentationalな、)component なのかの判別に、redux に connectさせるかどうかは関係ない(少なくとも、判の条件として優先順位それほど高くない)
139
+ - container なのか (presentationalな、)component なのかの判別に、redux に connectさせるかどうかは関係ない(少なくとも、判の条件として、最優先されるわけではない
140
140
 
141
141
 
142
142
 

4

テキスト修正

2019/09/15 16:18

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -100,7 +100,7 @@
100
100
 
101
101
 
102
102
 
103
- - Redux にconnectさせたものがcontainer/ で、それ以外は components/" 
103
+ - `components/` にあるコンポーネント `Xxx` を Redux にconnectさせるソースファイルを `XxxContainer.js` として `containers/` に作成する。
104
104
 
105
105
 
106
106
 

3

テキスト修正

2019/09/15 16:16

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -88,7 +88,7 @@
88
88
 
89
89
 
90
90
 
91
- - May contain both presentational and container components** inside but usually don’t have any DOM markup of their own except for some wrapping divs, and never have any styles.
91
+ - May contain both presentational and container components inside but usually don’t have any DOM markup of their own except for some wrapping divs, and never have any styles.
92
92
 
93
93
 
94
94
 

2

テキスト修正

2019/09/15 16:12

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -56,7 +56,7 @@
56
56
 
57
57
 
58
58
 
59
- - `components/` にはredux にconnect しないコンポーネントを書き、`components/` からimport したコンポーネントクラスを redux にconnect させたコンポーネントを `containers/` に入れる。(したがって `components/` の中に、 redux にconnectしたコンポーネントを置くのは禁止)
59
+ - `components/` にはredux にconnect しないコンポーネントを書き、`components/` からimport したコンポーネントを redux にconnect させたコンポーネントを `containers/` に入れる。(したがって `components/` の中に、 redux にconnectしたコンポーネントを置くのは禁止)
60
60
 
61
61
 
62
62
 

1

テキスト修正

2019/09/15 16:11

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -40,4 +40,194 @@
40
40
 
41
41
 
42
42
 
43
+
44
+
45
+
46
+
47
+ ### 追記
48
+
49
+
50
+
51
+ ソースコードのディレクトリ構造に、 `components/` と `containers/` というサブディレクトリーを作ったときに、どのようにコンポーネントを類別して、 `components/` と `containers/` に振り分けていくか?というのはけっこう悩みどころかと思います。
52
+
53
+
54
+
55
+ 小生の過去の react + redux の業務経験ですと、あるプロジェクトでは、
56
+
57
+
58
+
59
+ - `components/` にはredux にconnect しないコンポーネントを書き、`components/` からimport したコンポーネントクラスを redux にconnect させるたコンポーネントを `containers/` に入れる。(したがって `components/` の中に、 redux にconnectしたコンポーネントを置くのは禁止)
60
+
61
+
62
+
63
+ というルールだったところもありますし、
64
+
65
+
66
+
67
+ - `components/` には部品的なものを入れて `containers/` には、部品を配置した(いわば、"大きな" )コンポーネントを入れておく
68
+
69
+
70
+
71
+ というルールだったところもあります。
72
+
73
+
74
+
75
+ `containers/` には、その名のとおり「コンテナ(=容器)であるコンポーネント」を入れておくわけですが、この、"コンテナであるコンポーネント" とそうでないものとの2つに大別するという考え方は、Redux 作者のひとりであるDan Abramovさんの以下の記事が原典かと思います。
76
+
77
+
78
+
79
+ - [Presentational and Container Components](https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0)
80
+
81
+
82
+
83
+ 個人的には、上記に箇条書きで書かれている、 presentational components と container components それぞれの特徴を、満たす条件ととらえてすべてを厳密に守ろうとすると、融通がきかなくなってしまいがち、という所感を持っています。
84
+
85
+
86
+
87
+ 上記の記事を、ご質問に挙げられているコードに適用してみると、container components の特徴の中には、
88
+
89
+
90
+
91
+ - May contain both presentational and container components** inside but usually don’t have any DOM markup of their own except for some wrapping divs, and never have any styles.
92
+
93
+
94
+
95
+ というものがありますが、これに沿うと、このご質問にある `<Header />` も `<NavIcon />` を含んでいるので、containerコンポーネントである、と言えなくもないです。
96
+
97
+
98
+
99
+ ご質問のコンポーネント構成では、
100
+
101
+
102
+
103
+ - Redux にconnectさせたものがcontainer/ で、それ以外は components/" 
104
+
105
+
106
+
107
+ というルールにされているのかなと思いました。これはこれでアリな方針でありますが、これ以外の代替案として、
108
+
109
+
110
+
111
+ - まず `App` から import されている以下
112
+
113
+
114
+
115
+ Header, About, Top, MyPage, Login, Signup
116
+
117
+
118
+
119
+ は、 container とする。つまり App から直接 import されるものは、大きな部品と考えて差し支えないはずだから、container とする。
120
+
121
+
122
+
123
+ - 上記 6 個のcontainerコンポーネントから import されるコンポーネントで、少なくない数の部品的なコンポーネントをimport して、ひとつのまとまった外観と機能を提供するものも containerコンポーネントとする。
124
+
125
+
126
+
127
+ - 上記以外は、 ひとまず、`components/` に入れておき、 その後の修正で、presentational component から container component に "格上げ" してもいいかなと思えたものは、その時点で適宜 `containers/` に移動
128
+
129
+
130
+
131
+ - `components/` に入れておくものは Redux に connect してはダメというルールを、厳格に守ったほうがいいかはどうかはケースバイケースと考える。
132
+
133
+
134
+
135
+ 特に、上記のリストの最後の考え方を採用してしまうと、
136
+
137
+
138
+
139
+ - container なのか (presentationalな、)component なのかの判別に、redux に connectさせるかどうかは関係ない(少なくとも、判定の条件として優先順位はそれほど高くない)
140
+
141
+
142
+
143
+ ということになるわけですが、これを「そんなことを認めたら、収集がつかなくなるので認められない」と考えるか、「redux に connectさせるかどうかに縛られるよりも、 containerは大きな容れ物で、 component は containerに詰められる部品と考えたほうが、開発作業上のメリットが大きい」という考えを採用するかは、プロジェクトによって違っていました。
144
+
145
+
146
+
147
+ 最後の考え方を採用すると、 `components/header/NavIcon.js` を redux に connect させたものを export してよいことになるので、以下のようにも書いてよいことになります。
148
+
149
+
150
+
151
+ ```jsx
152
+
153
+ /**
154
+
155
+ * components/header/NavIcon.js
156
+
157
+ */
158
+
159
+ import React from 'react'
160
+
161
+
162
+
163
+ ・・・
164
+
165
+
166
+
167
+ class NavIcon extends React.Component {
168
+
169
+ ・・・
170
+
171
+ }
172
+
173
+
174
+
175
+ // withStylesを適用したNavIconをいったん変数に入れておく。
176
+
177
+ const StyledNavIcon = withStyles(styles, { withTheme: true })(NavIcon)
178
+
179
+
180
+
181
+ // 以下にて、 StyledNavIcon を redux に connectして、これを export default する。
182
+
183
+ const mapStateToProps = state => ({
184
+
185
+ open: state.NavIconReducer.open,
186
+
187
+ })
188
+
189
+
190
+
191
+ const mapDispatchToProps = dispatch => {
192
+
193
+ return{
194
+
195
+ handleToggleDrawer: () => dispatch(toggleDrawer())
196
+
197
+ }
198
+
199
+ }
200
+
201
+
202
+
203
+ // 上記の StyledNavIcon を redux にconnectする。
204
+
205
+ export default connect(mapStateToProps, mapDispatchToProps)(StyledNavIcon)
206
+
207
+
208
+
209
+ ```
210
+
211
+
212
+
213
+ そして、 `containers/` のほうに移動した、 `header/index.js` にて、
214
+
215
+
216
+
217
+ ```jsx
218
+
219
+ import NavIcon from '../../components/header/NavIcon'
220
+
221
+ ```
222
+
223
+ として、redux に connect済みのNavIconを `components/` からimportして使います。
224
+
225
+
226
+
227
+ もちろん上記の代替案のほうがいいといっているわけではありません。最終的にはメンバーの考えをもとにフロントエンドのリーダーが決定すべき、チームの方針かなと思います。
228
+
229
+
230
+
231
+
232
+
43
233
  以上、参考になれば幸いです。