React.jsを勉強しています。一つ気になるところがあったので、質問させていただきました。
変数を使用しないで、this.props.hogehogeという風に親のコンポーネントからプロパティを引き継いで使用するのはなぜでしょうか?コンポーネント外で宣言した変数ではダメなのでしょうか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
props
を使わずに外部のグローバル変数を参照することは可能です。しかしそれでは、書き換え困難になったり、再利用ができなく、とても不便なコンポーネントができがあってしまいます。次のような例を考えてみましょう。(例ではECMAScript 2015 + JSXを使っています。Babel等で変換して試して見てください。)
JavaScript
1let x = 42; 2 3class Answer extends React.Component { 4 render() { 5 let str = "答えは" + x + "だ。"; 6 return ( 7 <p> 8 {str} 9 </p> 10 ); 11 } 12} 13 14class UltimateQuestion extends React.Component { 15 render() { 16 return ( 17 <div> 18 <h3>生命、宇宙、全ての究極なる問い</h3> 19 <Answer /> 20 </div> 21 ); 22 } 23} 24 25ReactDOM.render( 26 <UltimateQuestion />, 27 document.getElementById("deep-thought") 28); 29 30/* 31このコードは次のように表示されます 32 生命、宇宙、全ての究極なる問い 33 答えは42だ。 34*/
さて、(ディープ・ソートが出した)答えは42でした。しかし、後から(13進数を使っていたという)致命的な間違いに気付きました。本当の答えは54になるはずでした。そこで、前の文はそのままで間違いを正すことにしましょう。
JavaScript
1 2let x = 42; 3 4class Answer extends React.Component { 5 render() { 6 let str = "答えは" + x + "だ。"; 7 return ( 8 <p> 9 {str} 10 </p> 11 ); 12 } 13} 14 15class UltimateQuestion extends React.Component { 16 render() { 17 return ( 18 <div> 19 <h3>生命、宇宙、全ての究極なる問い</h3> 20 <Answer /> 21 <p><em>というのは間違いで{x = 54,''}</em></p> 22 <Answer /> 23 </div> 24 ); 25 } 26} 27 28ReactDOM.render( 29 <UltimateQuestion />, 30 document.getElementById("deep-thought") 31); 32 33/* 34このコードは次のように表示されます 35 生命、宇宙、全ての究極なる問い 36 答えは54だ。 37 というのは間違いで 38 答えは54だ。 39*/
どちらも54になってしまいました。答えの仕方は決まっているのでAnswer
を再利用したのがまずかったのでしょうか?それではAnswer2
と別に作れば良かったのでしょうか?いや、そんなことをしたら、例えば、もし、英語版を作ろうとしたとき、Answer
とAnswer2
両方を変更する必要が出てきます。2個ぐらいならいいですけど、3個、4個、5個と増えていったら大変です!
では、どうしたらよかったのか。そう、props
として渡す形にしておけば別々の答えを渡すだけで良かったのです。
JavaScript
1class Answer extends React.Component { 2 render() { 3 let str = "答えは" + this.props.x + "だ。"; 4 return ( 5 <p> 6 {str} 7 </p> 8 ); 9 } 10} 11 12class UltimateQuestion extends React.Component { 13 render() { 14 return ( 15 <div> 16 <h3>生命、宇宙、全ての究極なる問い</h3> 17 <Answer x={42}/> 18 <p><em>というのは間違いで</em></p> 19 <Answer x={54}/> 20 </div> 21 ); 22 } 23} 24 25ReactDOM.render( 26 <UltimateQuestion />, 27 document.getElementById("deep-thought") 28); 29 30/* 31このコードは次のように表示されます 32 生命、宇宙、全ての究極なる問い 33 答えは42だ。 34 というのは間違いで 35 答えは54だ。 36*/
できました。真の正しい6×9の答えである54にちゃんと訂正できました。
今回は単純な構成なのでそれほど便利じゃなさそうに見えますが、これがもっと複雑で巨大で色んな所で使われているコンポーネントだったらどうでしょう?このコンポーネントを使う場合はx
の値を設定しておくなんて、非現実的だと想像つきませんか?設定し忘れていたら、表示はされないし、かといって設定したら、どこでどうコンポーネントが使われていて影響があるかわかりません。でも、props
であれば、プロパティとして渡した値しか影響は受けませんので、それぞれ独立に、安心して使うことができます。だからこそprops
を使うべきであり、プロパティとして渡している値(オブジェクト)以外から影響が絶対に無いようにコンポーネントを作るべきなのです。
投稿2016/07/05 11:18
総合スコア21735
0
ベストアンサー
差分レンダリングを行うために,propsで管理する必要があります.
React.js内のjsxで表示するような情報以外は,Reactのコンポーネント外で管理してしまっても構いません.
殆どの場合,jsxで表示するようなデータは変更されることを想定しているので,そういうときは propsでデータを管理し,変更を監視する必要があります.
js
1let hoge = ''; 2 3let ParentComponent = React.createClass({ 4 componentDidMount() { 5 setInterval(() => { 6 hoge = Math.random().toString(); 7 },100) 8 }, 9 10 render() { 11 return ( 12 <div> 13 <ComponentA data={hoge} /> 14 <ComponentB /> 15 </div> 16 ); 17 } 18});
js
1let ComponentA = React.createClass({ 2 render() { 3 <div> 4 {this.props.data} 5 </div> 6 } 7});
js
1setInterval(() => { 2 data = Math.random().toString(); 3},100); 4 5// Reactは props, state 以外でのデータの変更を察知できない. 6// この実装だと表示が更新されない 7// こういったデータは,props or state で管理されるべき. 8let ComponentB = React.createClass({ 9 render() { 10 <div> 11 {data} 12 </div> 13 } 14});
投稿2016/07/05 11:15
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。