(訳)他のライブラリ(jQueryプラグイン、Backbone)とともにReactを使用
reactは、任意のウェブアプリケーションで使用することができる.他のアプリケーションに埋め込むことができます.もちろん、十分注意すれば、他のアプリケーションもreactに埋め込むことができます.この文章はいくつかのよく使われる使用シーンから着手し,jQueryとbackboneとのインタラクションに重点を置く.しかし、中の考えは私たちが他のライブラリと対話するときに参考にすることができます.
DOMを操作するプラグインとのインタラクション
reactは管理外のdomの変化を感知しない.reactの更新はその内部の表現に依存し,同じDOMノードが他の操作可能なdomノードのプラグインによって変更されるとreact内部状態が混乱し回復できなくなる.
これはreactがDOMを操作するプラグインと一緒に共有できないという意味ではありません.各プラグインが何をしているのかをもっと理解する必要があります.
このような衝突を最も簡単に回避する方法はreactコンポーネントの更新を阻止することである.空の要素など、reactを更新する必要のない要素をレンダリングすることができます.
この問題をどう処理するか
この問題をよりよく説明するために、一般的なjqueryプラグインにwrapperを追加します.
まず、このノードにrefプロパティを追加します.componentDidMountメソッドでは,このノードの参照を取得することでjqueryプラグインに渡す.
reactがレンダリング中にこのノードを変更することを避けるためにrender()メソッドに空を返した.この空のノードには属性やサブノードがないので、Reactはそのノードを更新しません.このノードの制御権は完全にjQueryプラグインにあります.これによりreactとjqueryプラグインが同じdomを操作する問題は発生しません.
class SomePlugin extends React.Component { componentDidMount() { this.$el = $(this.el); this.$el.somePlugin(); } componentWillUnmount() { this.$el.somePlugin('destroy'); } render() { return
this.el = el} />; } }
, componentDidMount() componentWillUnmount() 。 jQuery DOM , componentWillUnmount 。 , 。 , 。
jQuery
, Chosen wrapper。Chosen 。 DOM , 。
Chosen
function Example() { return (
console.log(value)}> ); }
にするために,まずrenderメソッドのみのコンポーネントを する コンポーネントを いて した.renderメソッドでは
class Chosen extends React.Component {
render() {
return (
this.el = el}>
{this.props.children}
);
}
}
ラベルにラベルを けたことに してください.これは、 でラベルの ろに ノードを するため です.しかし、Reactの 、ラベルは 1つの ノードしかありません.これがReactの がChosenによって された のDOMノードと しないことを する です. なのは、Reactストリームの でDOMノードを した 、Reactが らかの でこれらのDOMノードを しないことを する があります.
に、ライフサイクルのフック を し けます.ノードの を してChosenを する があります.そしてcomponentDidUnmountで します.componentDidMount() { this.$el = $(this.el); this.$el.chosen(); } componentWillUnmount() { this.$el.chosen('destroy'); }
えておいてください.reactはthisにはしません.elフィールドには、 の な が されます. にrenderメソッドで を けない り.
はrenderであなたのコンポーネントを すれば ですが、 が したときに に してほしいと っています.なぜなら、 たちはChosenを じてjQueryのchangeイベントを したからです.
たちは thisをしません.props.Chosenに えてコンポーネントのプロパティは に される があり、ここにはイベントの も まれています.なぜなら、thisを び すためのhandleChangeメソッドを したからです.props.onChange.jQueryのchangeイベントに しました.つまり、changeイベントが すると.handleChangeメソッドが に されます.componentDidMount() { this.$el = $(this.el); this.$el.chosen(); this.handleChange = this.handleChange.bind(this); this.$el.on('change', this.handleChange); } componentWillUnmount() { this.$el.off('change', this.handleChange); this.$el.chosen('destroy'); } handleChange(e) { this.props.onChange(e.target.value); }
に、 たちはもう つしなければならないことがあります.Reactでは, は に である. えば、コンポーネントは、 コンポーネントの が すると、 なるchildrenを することができる.これは、インタラクションの で、 が されると、 でDOMの を する があり、reactでDOMノードを する がなくなります.
Chosenのドキュメントでは、 のDOM の を するためにjQueryのtrigger()メソッドを することをお めします.Reactは、の thisに を てます.props.childrenの .しかし、Chosenのchildrenリストの を する をcomponentDidUpdateのライフサイクル に します.componentDidUpdate(prevProps) { if (preProps.children !== this.props.children) { this.$el.trigger("chosen:updated"); } }
これにより,React によるノードが されると,ChosenはDOM の が であることを る.class Chosen extends React.Component { componentDidMount() { this.$el = $(this.el); this.$el.chosen(); this.handleChange = this.handleChange.bind(this); this.$(el).on('change', this.handleChange); } componentDidUpdate(prevProps) { if (prevProps.children !== this.props.children) { this.$el.trigger("chosen:updated"); } } componentWillUnmount() { this.$el.off('change', this.handleChange); this.$el.chosen('destory'); } handleChange(e) { this.props.onChange(e.target.value); } render() { return (
); } }
のビューライブラリと
なぜならrender()メソッドの により,Reactを のアプリケーションに め むことができる.
Reactは、 、あるDOM にReactノードをレンダリングするために する、ReactDOMである.render()は、UIの した によって び され、ボタンが さく、appが きくなる.
、これがReactがFacebookで われている です.これにより、Reactでアプリケーションを し、 のサーバでレンダリングされたテンプレートや のクライアントコードに することができます.
ベースのレンダリングをReactで するには
いくつかの いウェブアプリケーションでは、DOM を として きく き、$elを するのが です.html(html String)はDOMノードに されます.コードライブラリに たようなシーンがある は、reactを することをお めします. でレンダリングされた をreactコンポーネントに するだけでいいです. はjQueryの です$('#container').html(''); $('#btn').click(function() { alert('Hello!'); });
reactの にfunction Button() { return ; } ReactDOM.render(
, react react 。 , id, 。 , react ,
function Button(props) { return ; } function HelloButton() { function handleClick() { alert('Hello!'); } return
, ReactDOM.render() DOM 。 , app react , 。 , ReactDOM.render() 。
React Backbone
Backbone HTML , , DOM 。 , React 。
, Backbone ParagraphView. React
, Backbone (this.el) DOM Backbone render() . , ReactDOM.render() . function Paragraph(props) { return
{props.text}
; } const ParagraphView = Backbone.View.extend({ render() { const text = this.model.get('text'); ReactDOM.render(, this.el); return this; }, remove() { ReactDOM.unmountComponentAtNode(this.el); Backbone.View.prototype.remove.call(this); } });
なことはremoveメソッドでReactDOMを び さなければならないことです.unmountComponentAtNode()メソッドは、reactによって されたイベントおよびその のリソースを します.
コンポーネントがreactツリーから されると、 のクリーンアップ が に されます.しかし、ツリー を で したので、このメソッドを び してクリーンアップ を わなければなりません.
Modelレイヤとのインタラクション
、reactアプリケーションを するためにreact state、Flux、またはReduxなどの データストリームを することを します. 、reactは のフレームワークやライブラリのModelレイヤを して することもできます.
reactアプリケーションでBackboneを するモデル
ReactコンポーネントでBackboneのmodelとcollectionsを する も な は、さまざまなchangeイベントをリスニングし、 で することです.
Modelsをレンダリングするコンポーネントは「change」イベントをリスニングし、collectionsをレンダリングするコンポーネントは「add」イベントと「remove」イベントをリスニングします. に、thisを び します.forceUpdate()は、 しいデータを してコンポーネントを レンダリングします.
の では、ListコンポーネントがBackboneコンテナをレンダリングします.また、Itemコンポーネントを して アイテムをレンダリングします.class Item extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); } handleChange() { this.forceUpdate(); } componentDidMount() { this.props.model.on('change', this.handleChange); } componentWillUnmount() { this.props.model.off('change', this.handleChange); } render() { return
{this.props.model.get('text')} ; } } class List extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); } handleChange() { this.forceUpdate(); } componentDidMount() { this.props.collection.on('add', 'remove', this.handleChange); } componentWillUnmount() { this.props.collection.off('add', 'remove', this.handleChange); } render() { return ({this.props.collection.map(model => (
); } }- ))}
BackboneのModelsからデータを
の では、ReactコンポーネントがBackboneのModelsとCollectionsを できることが されています.その 、 のデータ スキームを する は、Backboneの の にもっと する があります.
この を する1つの は,modelの が すると,それを のデータとして し,この を の に することである. に すのは、Backboneのmodelレイヤのプロパティをstateに し、ラップされたコンポーネントにデータを す コンポーネントです.
このように,この コンポーネントだけがBackbone Modelsの を る があり,ほとんどのコンポーネントはBackboneに して である.
の では、 stateとしてModelのプロパティをコピーします. たちはchangeイベント(unmountingで をキャンセル)を し、changeイベントを するときにmodelの の でstateを します. に、モデルのプロパティが で された 、 いモデルから をキャンセルし、 しいモデルを することを れないでください.
この はBackboneとのコラボレーションの を するためではなく、この を じてこのような を する な を する があります.function connectToBackboneModel(WrappedComponent) { return class BackboneComponent extends React.Component { constructor(props) { super(props); this.state = Object.assign({}, props.model.attributes); this.handleChange = this.handleChange.bind(this); } componentDidMount() { this.props.model.on('change', this.handleChange); } componentWillReceiveProps(nextProps) { this.setState(Object.assign({}, nextProps.model.attributes)); if (nextProps.model !== this.props.model) { this.props.model.off('change', this.handleChange); nextProps.model.on('change', this.handleChange); } } componentWillUnmount() { this.props.model.off('change', this.handleChange); } handleChange(model) { this.setState(model.changedAttributes()); } render() { const propsExceptModel = Object.assign({}, this.props); delete propsExceptModel.model; return
; } } }
を するために、reactコンポーネントNameInputとBackboneのmodelレイヤを み わせて し、 が されるたびにfirstNameプロパティが されます.function NameInput(props) { return (
); } const BackboneNameInput = connectToBackboneModel(NameInput); function Example(props) { function handleChange(e) { model.set('firstName', e.target.value); } return (
My name is {props.firstName}.); } const model = new Backbone.Model({ firstName: 'Frodo' }); ReactDOM.render( , document.getElementById('root') );
これらの はBackboneに らない.Reactと のmodelライブラリを して、ライフサイクルでその を し、 にreactのstateにデータをコピーすることもできます.