Reactjsのチュートリアルを読んで浮かんだ疑問とそれに対する答え
Reactjsのチュートリアルを読んでみて、大雑把なReactjsの使い方を把握したのですが、疑問に思った点がいくつかあったので調べてみました。
前提
筆者のReactjs力がどれくらいかと言うと
- 存在は知ってたが、中身は全く知らなかった
- VirtualDom - なぜ仮想DOMという概念が俺達の魂を震えさせるのかを読んだ
だけの状態です。つまりコンセプトは知っているが、細かい話は何も知らなかった状態です。その状態で前述のチュートリアルを読んだ感じです。
疑問
Q. どうやってcomponentの解決をしている?
var CommentBox = React.createClass({
render: function() {
return (
<div className="commentBox">
Hello, world! I am a CommentBox.
</div>
);
}
});
React.render(
<CommentBox />, // この部分
document.getElementById('content')
);
var CommentBox = React.createClass({
render: function() {
return (
<div className="commentBox">
Hello, world! I am a CommentBox.
</div>
);
}
});
React.render(
<CommentBox />, // この部分
document.getElementById('content')
);
CommentBox
は単なる変数の名前なので、reactjs側からは CommentBox
という名前のcomponentがいることは分からないはずなのに、 React.render
する時に <CommentBox />
と書けるのは何故だろう?
A. JSX展開後に CommentBox
変数を直接使っている
先ほどのコードをJSXの翻訳機に通すと次のようなコードになります。
var CommentBox = React.createClass({displayName: 'CommentBox',
render: function() {
return (
React.createElement('div', {className: "commentBox"},
"Hello, world! I am a CommentBox."
)
);
}
});
React.render(
React.createElement(CommentBox, null), // ここ
document.getElementById('content')
);
見れば分かるように CommentBox
変数を直接使っています。チュートリアル中では特にスコープの話は出てきませんが、componentを使う場合はそのクラスが参照できなければいけないようです。
というわけなので、こんな感じでモジュール化しても大丈夫そうです。
define('CommentBox', ['react'], function (React) {
return React.createClass(/* .. */)
});
require(['react', 'CommentBox'], function (React, CommentBox) {
React.render(
<CommentBox />,
document.getElementById('content')
);
});
Q. propsとstateの違いは何?
各componentはpropsとstateを持っています。これらは両方共 render()
時に使うのが主な使い方のようだけど、わざわざ2種類用意しているのは何故?
A. propsはimmutable、stateが変更されると再描画される
propsは変更しない(immutable)が、stateはそうではないとのこと。
Reactjsではアプリケーションをcomponentの階層として実装し、全体としては木構造になります。あるcomponentのstateが setState()
によって変更されると、Reactjsはそのcomponentにdirtyフラグを立てます。
そして処理が終わった段階でdirtyなcomponentとその子供達を全てrenderします。
こうすることで新しい仮想DOMを構築するコストを極限まで減らしています。また仮想DOMの差分を計算する際も、変更されている可能性があるcomponentに絞って計算すればいいことになります。
Q. propsとstateの使い分けは?
A. いくつかのチェックリストがあるのでそれを参考にする
- 親から渡されるものなら、それはおそらくstateではない
- 時間とともに変化するものでないなら、それはおそらくstateではない
- 他のstateやpropsから計算できるなら、それは確実にstateではない
stateは一般的に親で管理され、それを使って子にpropsが渡されるようです。なので、stateを管理すべきcomponentは
- そのstateを使って描画される全てのcompnentの共通の親
- もしくはそれより上のcomponent
- いいのが無い場合はstateを保持するだけのcomponentを上位階層に作ってもいい
Q. component終了時にメモリリークを防ぐには?
例えば Backbone.View
からあるHTML要素を参照していて、その要素がReactjsによって削除された場合、そのviewオブジェクトからの参照を消さないと、メモリリークが発生してしまいます。
HTML要素に直接紐付いているイベントハンドラだったら、 componentWillUnmount
時に頑張れば終了処理を実行できそうですが、単なるJSオブジェクトの場合はどうすればいいの?
A. viewオブジェクトの作成から終了までをcomponentにやらせる
そもそもReactのあずかり知らないところでHTML要素への参照を保持することが間違っているのだろうと思います。つまり Backbone.View
を使いたいなら、そのインスタンスは componentDidMount
で作成して参照をcomponentにもたせておき、 componentWillUnmount
で削除する訳です。
var CommentBox = React.createClass({
componentDidMound: function () {
this.view = new Backbone.View({ el: this.refs.foo.getDOMNode() });
},
componentWillUnmount: function () {
this.view.remove();
},
render: function() {
return (
<div className="commentBox" ref="foo">
Hello, world! I am a CommentBox.
</div>
);
}
});
おわりに
Reactjsは思想・使い方を含めて非常にシンプルで、理解しやすい印象でした。面倒な箇所をJSXに押し付けているので、JSレベルでは、書いてあることとその挙動が把握しやすくなっているのがいいですね。
Author And Source
この問題について(Reactjsのチュートリアルを読んで浮かんだ疑問とそれに対する答え), 我々は、より多くの情報をここで見つけました https://qiita.com/yuku_t/items/f453839377317e013537著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .