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

回答編集履歴

14

テキスト修正

2019/01/18 06:25

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -182,8 +182,14 @@
182
182
 
183
183
  ### 追記4
184
184
 
185
- 以下の質問と同じ要望と思いす。
185
+ コメントら頂きした、
186
186
 
187
+ > hfidk 2019/01/17 18:13
188
+ >
189
+ 余計な質問すいません,追加するタグの名前をオブジェクトのキー名にすることってできませんか?
190
+
191
+ とのご質問への回答です。これは以下の質問と同じ要望かと思います。
192
+
187
193
  - stackoverflow: [Create an instance of a React class from a string](https://stackoverflow.com/questions/30172433/create-an-instance-of-a-react-class-from-a-string)
188
194
 
189
195
  上記への回答、

13

テキスト修正

2019/01/18 06:25

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -248,7 +248,7 @@
248
248
  - 動作確認用サンプル: [https://jsfiddle.net/jun68ykt/0zc3L7ke/7/](https://jsfiddle.net/jun68ykt/0zc3L7ke/7/)
249
249
 
250
250
 
251
- キーとなる文字列とコンポーネントをマップするオブジェクト `tagComponents` を作るというのが、ひと手間かかりますが、いったんルールを決めて作ってしまえば、追加していくのはそれほど大変ではありません。私自身、時々、業務でも使います。
251
+ キーとなる文字列とコンポーネントをマップするオブジェクト `tagComponents` を作るというのが、ひと手間かかりますが、いったんルールを決めて作ってしまえば、追加していくのはそれほど大変ではありません。私自身、時々、業務でも使う小技です。
252
252
 
253
253
  肝は、
254
254
  ```javascript

12

テキスト修正

2019/01/17 10:38

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -258,4 +258,4 @@
258
258
  ```javascript
259
259
  const tag = tagComponents[this.props.tag] || FooTag;
260
260
  ```
261
- としてまって、 `<tag />` と書いても意図したようには表示されません。
261
+ として `<tag />` と書いても意図したようには表示されません。

11

テキスト修正

2019/01/17 10:33

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -178,4 +178,84 @@
178
178
  </div>
179
179
  );
180
180
  }
181
- ```
181
+ ```
182
+
183
+ ### 追記4
184
+
185
+ 以下の質問と同じ要望かと思います。
186
+
187
+ - stackoverflow: [Create an instance of a React class from a string](https://stackoverflow.com/questions/30172433/create-an-instance-of-a-react-class-from-a-string)
188
+
189
+ 上記への回答、
190
+ - [https://stackoverflow.com/a/30172587/4643029](https://stackoverflow.com/a/30172587/4643029)
191
+
192
+ にある
193
+
194
+ > So you simply need to find a way to map between the string "Home" and the component class Home. A simple object will work as a basic registry, and you can build from there if you need more features.
195
+
196
+ ```javascript
197
+ var components = {
198
+ "Home": Home,
199
+ "Other": OtherComponent
200
+ };
201
+
202
+ var Component = components[this.props.template];
203
+ ```
204
+
205
+
206
+ を参考にすればよいです。以下簡単なサンプルです。
207
+
208
+ 3つのタグコンポーネント `FooTag`, `BarTag`, `BazTag` があります。`App` のprops `tag` に `"foo"`,`"bar"`,`"baz"` のいずれかが渡ってくる想定で、これらの文字列から表示対象のタグコンポーネントを変数 `Tag` に入れて、これをJSX形式で書いて表示するという例です。
209
+
210
+ ```jsx
211
+ class FooTag extends React.Component {
212
+ render() {
213
+ return <span>This is a FooTag.</span>;
214
+ }
215
+ }
216
+
217
+ class BarTag extends React.Component {
218
+ render() {
219
+ return <span>This is a BarTag.</span>;
220
+ }
221
+ }
222
+
223
+ class BazTag extends React.Component {
224
+ render() {
225
+ return <span>This is a BazTag.</span>;
226
+ }
227
+ }
228
+
229
+ const tagComponents = {
230
+ foo: FooTag,
231
+ bar: BarTag,
232
+ baz: BazTag,
233
+ };
234
+
235
+ class App extends React.Component {
236
+ render() {
237
+ const Tag = tagComponents[this.props.tag] || FooTag;
238
+ return (
239
+ <div className="app">
240
+ <Tag />
241
+ </div>
242
+ );
243
+ }
244
+ }
245
+
246
+ ReactDOM.render(<App tag="bar" />, document.querySelector("#app"));
247
+ ```
248
+ - 動作確認用サンプル: [https://jsfiddle.net/jun68ykt/0zc3L7ke/7/](https://jsfiddle.net/jun68ykt/0zc3L7ke/7/)
249
+
250
+
251
+ キーとなる文字列とコンポーネントをマップするオブジェクト `tagComponents` を作るというのが、ひと手間かかりますが、いったんルールを決めて作ってしまえば、追加していくのはそれほど大変ではありません。私自身、時々、業務でも使います。
252
+
253
+ 肝は、
254
+ ```javascript
255
+ const Tag = tagComponents[this.props.tag] || FooTag;
256
+ ```
257
+ と、`Tag`のような、大文字で始まる変数名に代入することです。こうすると `<Tag />` と書けますが、これを
258
+ ```javascript
259
+ const tag = tagComponents[this.props.tag] || FooTag;
260
+ ```
261
+ としてまって、 `<tag />` と書いても意図したようには表示されません。

10

テキスト修正

2019/01/17 10:11

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -140,7 +140,7 @@
140
140
  }
141
141
  ```
142
142
 
143
- 上記を以下のように修正してみるといかがでしょうか? (こんどは`push`で大丈夫です。)
143
+ これだと、`components_Data` に複数タグ分のデータがあったときに、setStateが複数回呼ばれてしまいます。ですので、上記を以下のように修正してみるといかがでしょうか? (こんどは`push`で大丈夫です。)
144
144
 
145
145
  **修正後:**
146
146
  ```javascript
@@ -159,7 +159,7 @@
159
159
 
160
160
  すなわち、 `forEach` のループに入る前に、 `drawnTag` というローカル変数で空配列の配列を用意しておき、 `forEach` のループでこの配列に `<Comp />` を追加していきます。そして、`forEach`を抜けた後に、
161
161
  `this.setState({ drawnTag });`
162
- で、state に反映させるようにして、 `getInfo`が呼ばれたときに `setState` が1回だけ実行されるようにます。
162
+ で、state に反映させるようにします。こうすることで`getInfo`が呼ばれたときに `setState` が1回だけ実行されるようになります。
163
163
 
164
164
  上記の趣旨の修正をお手元のコードにしてみると意図通り動くかもしれません。
165
165
 

9

テキスト修正

2019/01/17 02:32

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -118,4 +118,64 @@
118
118
  `"Nothing was returned from render." `
119
119
  は出なくなると思います。
120
120
 
121
- その上で Clock を使う側では `<Clock view="horizontal" />` または `<Clock view="vertical" />` というように、適切な値の`view`をpropsで渡すようにすればよいかと思います。逆に、表示したときにスタイルがあたらずに時と分が表示されたら、それは `view`の値が適切にprops経由で渡せていないと気がつくことができます。
121
+ その上で Clock を使う側では `<Clock view="horizontal" />` または `<Clock view="vertical" />` というように、適切な値の`view`をpropsで渡すようにすればよいかと思います。逆に、表示したときにスタイルがあたらずに時と分が表示されたら、それは `view`の値が適切にprops経由で渡せていないと気がつくことができます。
122
+
123
+
124
+ ### 追記3
125
+
126
+ ご質問にあるコードの以下の部分で、 `forEach` の中で setState しているのが怪しいです。
127
+
128
+ **修正前:**
129
+ ```
130
+ getInfo = () =>{
131
+ var ref_Data = require('../users_mirror.json');
132
+ var components_Data = ref_Data.users[this.props.account_Name].components;
133
+ Object.keys(components_Data).forEach(function(key){
134
+ if(components_Data[key]){
135
+ this.setState({
136
+ drawnTag: this.state.drawnTag.push(<Comp />)
137
+ });
138
+ }
139
+ }.bind(this));
140
+ }
141
+ ```
142
+
143
+ 上記を以下のように修正してみるといかがでしょうか? (こんどは`push`で大丈夫です。)
144
+
145
+ **修正後:**
146
+ ```javascript
147
+ getInfo = () =>{
148
+ var ref_Data = require('../users_mirror.json');
149
+ var components_Data = ref_Data.users[this.props.account_Name].components;
150
+ var drawnTag = [];
151
+ Object.keys(components_Data).forEach(function(key){
152
+ if(components_Data[key]){
153
+ drawnTag.push(<Comp />);
154
+ }
155
+ });
156
+ this.setState({ drawnTag });
157
+ };
158
+ ```
159
+
160
+ すなわち、 `forEach` のループに入る前に、 `drawnTag` というローカル変数で空配列の配列を用意しておき、 `forEach` のループでこの配列に `<Comp />` を追加していきます。そして、`forEach`を抜けた後に、
161
+ `this.setState({ drawnTag });`
162
+ で、state に反映させるようにして、 `getInfo`が呼ばれたときに `setState` が1回だけ実行されるようにします。
163
+
164
+ 上記の趣旨の修正をお手元のコードにしてみると意図通り動くかもしれません。
165
+
166
+ それと、 `console.log(this.state.drawnTag);` というデバッグログは、以下のように render の中で行うのがよいです。一度、他の箇所にある`console.log(this.state.drawnTag);` をコメントアウトして、以下の箇所にだけ入れてみることをお勧めします。
167
+
168
+ ```javascript
169
+ render() {
170
+ console.log(this.state.drawnTag);
171
+ return (
172
+ <div>
173
+ {this.state.drawnTag.map((item, i) =>
174
+ <React.Fragment key={i}>
175
+ <div>{item}</div>
176
+ </React.Fragment>)
177
+ }
178
+ </div>
179
+ );
180
+ }
181
+ ```

8

テキスト修正

2019/01/17 02:15

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -71,6 +71,12 @@
71
71
   
72
72
   
73
73
   
74
+ 修正方法ですが、`render()` の終わりの `}` の直前に
75
+ ```javascript
76
+ return <div>{this.state.hours}{this.state.minutes}</div>;
77
+ ```
78
+ を追加して、 以下のようにします。 
79
+  
74
80
  **修正後:**
75
81
  ```jsx
76
82
  render() { //デジタル時計のデザインをpropsで管理できるようにした."view=''"で"vertical"で水平に"horizontal"で縦並びに
@@ -108,13 +114,7 @@
108
114
  }
109
115
  ```
110
116
 
111
- 上記のように、 `render()` の終わりの `}` の直前
112
- ```javascript
113
- return <div>{this.state.hours}{this.state.minutes}</div>;
114
- ```
115
- を追加して、 `Clock` の props `view` が与えられなかったり、与えられても`horizontal`または`vertical`のいずれでもない場合に、とりあえず`{this.state.hours}`と`{this.state.minutes}`を並べて、 classNameやstyleを指定しない単なる `<div>`で囲んだものを返すようにしておきます。
116
-
117
- このようにしておけば、Clock を使う側で `<Clock />` のように `view`を指定し忘れても、
117
+ のように修正すると`Clock` の props `view` が与えられなかったり、与えられても`horizontal`または`vertical`いずれでもない場合に、とあえず`{this.state.hours}`と`{this.state.minutes}`を並べて、 classNameやstyleを指定しない単なる `<div>`で囲んだもを返すようになり、Clock を使う側で `<Clock />` のよう`view`を指定し忘れても、
118
118
  `"Nothing was returned from render." `
119
119
  は出なくなると思います。
120
120
 

7

テキスト修正

2019/01/16 05:49

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -112,8 +112,10 @@
112
112
  ```javascript
113
113
  return <div>{this.state.hours}{this.state.minutes}</div>;
114
114
  ```
115
- を追加して、 `Clock` の props `view` が与えられなかったり、与えられても`horizontal`または`vertical`のいずれでもない場合に、とりあえず何もスタイルをあてないで、`{this.state.hours}`と`{this.state.minutes}`を並べて `<div>`で囲んだものを返すようにしておきます。
115
+ を追加して、 `Clock` の props `view` が与えられなかったり、与えられても`horizontal`または`vertical`のいずれでもない場合に、とりあえず`{this.state.hours}`と`{this.state.minutes}`を並べて classNameやstyleを指定しない単なる `<div>`で囲んだものを返すようにしておきます。
116
116
 
117
- とりあえず上記のようにしておけば、Clock を使う側で `<Clock />` のように `view`を指定し忘れても、`"Nothing was returned from render." ` は出なくなると思います。
117
+ のようにしておけば、Clock を使う側で `<Clock />` のように `view`を指定し忘れても、
118
+ `"Nothing was returned from render." `
119
+ は出なくなると思います。
118
120
 
119
- その上で Clock を使う側では `<Clock view="horizontal" />` または `<Clock view="vertical" />` というように、適切な値の`view`をpropsで渡すようにすればよいかと思います。スタイルがあたらずに時と分が表示されたら、それは `view`の値が適切にprops経由で渡せていないと気がつくことができます。
121
+ その上で Clock を使う側では `<Clock view="horizontal" />` または `<Clock view="vertical" />` というように、適切な値の`view`をpropsで渡すようにすればよいかと思います。逆に、表示したときにスタイルがあたらずに時と分が表示されたら、それは `view`の値が適切にprops経由で渡せていないと気がつくことができます。

6

テキスト修正

2019/01/16 04:58

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -116,4 +116,4 @@
116
116
 
117
117
  とりあえず上記のようにしておけば、Clock を使う側で `<Clock />` のように `view`を指定し忘れても、`"Nothing was returned from render." ` は出なくなると思います。
118
118
 
119
- その上でClock を使う側では `<Clock view="horizontal" />` または `<Clock view="vertical" />` というように、`view`をpropsで渡すようにすればよいかと思います。スタイルがあたらずに時と分が表示されたら、それは `view`の値が適切にprops経由で渡せていないと気がつくことができます。
119
+ その上で Clock を使う側では `<Clock view="horizontal" />` または `<Clock view="vertical" />` というように、適切な値の`view`をpropsで渡すようにすればよいかと思います。スタイルがあたらずに時と分が表示されたら、それは `view`の値が適切にprops経由で渡せていないと気がつくことができます。

5

テキスト修正

2019/01/16 04:43

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -108,7 +108,11 @@
108
108
  }
109
109
  ```
110
110
 
111
- 上記のように、 `render()` の終わりの `}` の直前に `return <div>{this.state.hours}{this.state.minutes}</div>;` を追加して、 `Clock` の props `view` が与えられなかったり、与えられても`horizontal`または`vertical`のいずれでもない場合に、とりあえず何もスタイルをあてないで、`{this.state.hours}`と`{this.state.minutes}`を並べて `<div>`で囲んだものを返すようにしておきます。
111
+ 上記のように、 `render()` の終わりの `}` の直前に
112
+ ```javascript
113
+ return <div>{this.state.hours}{this.state.minutes}</div>;
114
+ ```
115
+ を追加して、 `Clock` の props `view` が与えられなかったり、与えられても`horizontal`または`vertical`のいずれでもない場合に、とりあえず何もスタイルをあてないで、`{this.state.hours}`と`{this.state.minutes}`を並べて `<div>`で囲んだものを返すようにしておきます。
112
116
 
113
117
  とりあえず上記のようにしておけば、Clock を使う側で `<Clock />` のように `view`を指定し忘れても、`"Nothing was returned from render." ` は出なくなると思います。
114
118
 

4

テキスト修正

2019/01/16 04:41

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -102,13 +102,13 @@
102
102
  </div>
103
103
  </div>
104
104
  );
105
- } else {
106
- return <div>{this.state.hours}{this.state.minutes}</div>;
107
105
  }
106
+
107
+ return <div>{this.state.hours}{this.state.minutes}</div>; // この行を追加
108
108
  }
109
109
  ```
110
110
 
111
- 上記のように、 `else { return <div>{this.state.hours}{this.state.minutes}</div>; }` を追加して、 `Clock` の props `view` が与えられなかったり、与えられても`horizontal`または`vertical`のいずれでもない場合に、とりあえず何もスタイルをあてないで、`{this.state.hours}`と`{this.state.minutes}`を並べて `<div>`で囲んだものを返すようにしておきます。
111
+ 上記のように、 `render()` の終わりの `}` の直前に `return <div>{this.state.hours}{this.state.minutes}</div>;` を追加して、 `Clock` の props `view` が与えられなかったり、与えられても`horizontal`または`vertical`のいずれでもない場合に、とりあえず何もスタイルをあてないで、`{this.state.hours}`と`{this.state.minutes}`を並べて `<div>`で囲んだものを返すようにしておきます。
112
112
 
113
113
  とりあえず上記のようにしておけば、Clock を使う側で `<Clock />` のように `view`を指定し忘れても、`"Nothing was returned from render." ` は出なくなると思います。
114
114
 

3

テキスト修正

2019/01/16 03:11

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -26,6 +26,90 @@
26
26
 
27
27
  以上参考になれば幸いです。
28
28
 
29
- ### 補足
29
+ ### 追記1
30
30
 
31
- componentWillMount は [React 16.3から非推奨メソッドになった](https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#gradual-migration-path)ので、v16.3以降を使用の際は、替わりに componentDidMount を使うことをお勧めします。
31
+ componentWillMount は [React 16.3から非推奨メソッドになった](https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#gradual-migration-path)ので、v16.3以降を使用の際は、替わりに componentDidMount を使うことをお勧めします。
32
+
33
+ ### 追記2
34
+
35
+ `Clock` の `render` で発生している `"Nothing was returned from render." ` というエラーは、以下の修正でとりあえず発生しなくなると思います。
36
+
37
+ **修正前:**
38
+ ```jsx
39
+ render() { //デジタル時計のデザインをpropsで管理できるようにした."view=''"で"vertical"で水平に"horizontal"で縦並びに
40
+ if (this.props.view === "horizontal") {
41
+ return (
42
+ <div
43
+ style={{}}
44
+ className="clock_flame"
45
+ >
46
+ <span id="clock_hour">
47
+ {this.state.hours}
48
+ </span>
49
+ <span id="clock_minute">
50
+ {this.state.minutes}
51
+ </span>
52
+ </div>
53
+ )
54
+ } else if (this.props.view === "vertical") {
55
+ return (
56
+ <div
57
+ style={{}}
58
+ className="clock_flame_vertical"
59
+ >
60
+ <div id="clock_hour_vertical" className="vertical">
61
+ {this.state.hours}
62
+ </div>
63
+ <div id="clock_minute_vertical" className="vertical">
64
+ {this.state.minutes}
65
+ </div>
66
+ </div>
67
+ );
68
+ }
69
+ }
70
+ ```
71
+  
72
+  
73
+  
74
+ **修正後:**
75
+ ```jsx
76
+ render() { //デジタル時計のデザインをpropsで管理できるようにした."view=''"で"vertical"で水平に"horizontal"で縦並びに
77
+ if (this.props.view === "horizontal") {
78
+ return (
79
+ <div
80
+ style={{}}
81
+ className="clock_flame"
82
+ >
83
+ <span id="clock_hour">
84
+ {this.state.hours}
85
+ </span>
86
+ <span id="clock_minute">
87
+ {this.state.minutes}
88
+ </span>
89
+ </div>
90
+ )
91
+ } else if (this.props.view === "vertical") {
92
+ return (
93
+ <div
94
+ style={{}}
95
+ className="clock_flame_vertical"
96
+ >
97
+ <div id="clock_hour_vertical" className="vertical">
98
+ {this.state.hours}
99
+ </div>
100
+ <div id="clock_minute_vertical" className="vertical">
101
+ {this.state.minutes}
102
+ </div>
103
+ </div>
104
+ );
105
+ } else {
106
+ return <div>{this.state.hours}{this.state.minutes}</div>;
107
+ }
108
+ }
109
+ ```
110
+
111
+ 上記のように、 `else { return <div>{this.state.hours}{this.state.minutes}</div>; }` を追加して、 `Clock` の props `view` が与えられなかったり、与えられても`horizontal`または`vertical`のいずれでもない場合に、とりあえず何もスタイルをあてないで、`{this.state.hours}`と`{this.state.minutes}`を並べて `<div>`で囲んだものを返すようにしておきます。
112
+
113
+ とりあえず上記のようにしておけば、Clock を使う側で `<Clock />` のように `view`を指定し忘れても、`"Nothing was returned from render." ` は出なくなると思います。
114
+
115
+ その上で、Clock を使う側では `<Clock view="horizontal" />` または `<Clock view="vertical" />` というように、`view`をpropsで渡すようにすればよいかと思います。スタイルがあたらずに時と分が表示されたら、それは `view`の値が適切にprops経由で渡せていないと気がつくことができます。

2

テキスト修正

2019/01/16 02:06

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -28,4 +28,4 @@
28
28
 
29
29
  ### 補足
30
30
 
31
- componentWillMount は [React 16.3から非推奨メソッドになった](https://medium.com/@baphemot/whats-new-in-react-16-3-d2c9b7b6193b)ので、v16.3以降を使用の際は、替わりに componentDidMount を使うことをお勧めします。
31
+ componentWillMount は [React 16.3から非推奨メソッドになった](https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#gradual-migration-path)ので、v16.3以降を使用の際は、替わりに componentDidMount を使うことをお勧めします。

1

テキスト修正

2019/01/15 02:32

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -24,4 +24,8 @@
24
24
 
25
25
  > メソッドが呼び出されたオブジェクトの新しい length プロパティ。
26
26
 
27
- 以上参考になれば幸いです。
27
+ 以上参考になれば幸いです。
28
+
29
+ ### 補足
30
+
31
+ componentWillMount は [React 16.3から非推奨メソッドになった](https://medium.com/@baphemot/whats-new-in-react-16-3-d2c9b7b6193b)ので、v16.3以降を使用の際は、替わりに componentDidMount を使うことをお勧めします。