jQueryからReact.jsへ移行する方法とは?[閉鎖しました]
質問
ここ数日、Reactについて読み漁っています。私は見ているもののほとんどを理解することができますが、私はそれを書く能力に完全に自信を持っていません。私は、jQueryと要素を互いに追加することによって、そのhtml生成のすべてを行う小さなWebアプリに取り組んできました。これをReactで再構築すると速くなると思うので、試してみたいと思っています。この JSFiddle は、私が取り組んでいるようなことの小さな例です。Reactでどう書きますか?
JSです。
function remove() {
this.remove();
}
function timed_append_new_element() {
setTimeout(function () {
var added_content = $("<span />", {
class: "added_content",
text: "Click to close",
click: remove
});
container.append(added_content);
}, 3000);
}
function append_new_element() {
var added_content = $("<span />", {
class: "timed_added_content",
text: "Click to close",
click: remove
});
container.append(added_content);
}
var container = $("<div />", {
class: "container"
});
var header = $("<span />", {
class: "header",
text: "jQuery to React.js Header"
});
var add_button = $("<button />", {
class: "add_button",
text: "Add Element",
click: append_new_element
});
var timed_add_button = $("<button />", {
class: "add_button",
text: "Add Element in 3 seconds",
click: timed_append_new_element
});
container.append(header);
container.append(add_button);
container.append(timed_add_button);
$("body").append(container);
どのように解決するのですか?
良いReactアプリケーションを構築するのに役立つかもしれない、心に留めておくべきいくつかの基本的な考え方があります。
UIはデータの関数であるべきです。
多くの jQuery スープスタイルのアプリケーションでは、アプリケーションのビジネス ロジック、アプリケーションのデータ、および UI インタラクション コードがすべて混在しています。このため、この種のアプリケーションはデバッグが困難であり、特に成長が困難です。Reactは、多くの最新のクライアントサイドアプリケーションフレームワークと同様に、UIはデータの単なる表現であるという考えを強制します。UI を変更したい場合は、データの一部を変更し、フレームワークが使用するどのようなバインディング システムでも UI を更新できるようにする必要があります。
Reactでは、各コンポーネントは(理想的には)2つのデータのピースの関数です。 プロパティ コンポーネントのインスタンスに渡される 状態 があります。同じプロパティ(または "props")と状態が与えられると、コンポーネントは同じようにレンダリングされるはずです。
これは、具体的な例がないため、少し抽象的な考えとなりますが、とりあえずはこのまま進めていきます。
DOMに触れない
Reactでは、他のデータバインドフレームワークよりもさらに、可能な限りDOMを直接操作しないようにする必要があります。React のパフォーマンスと複雑さの特徴の多くは、React が実際の DOM を操作するために、内部で異なるアルゴリズムを持つ仮想 DOM を使用しているからこそ可能なのです。DOMを操作するコンポーネントを作るときはいつでも、Reactの仮想DOM機能を使って同じ機能をよりイディオムに作ることができないか自問自答すべきです。
もちろん、時にはDOMにアクセスする必要があったり、Reactで再構築せずにjQueryプラグインを組み込んだりすることもあるでしょう。このようなとき、Reactは優れた コンポーネントライフサイクルフック を利用することで、Reactのパフォーマンスがあまり低下しないようにすることができます(または、場合によっては、コンポーネントが完全に壊れないようにすることもできます)。
DOM を操作しないことは、上記の "UI as a function of the data, " と密接に関係します。
データフローを反転させる
大規模なReactアプリケーションでは、どのサブコンポーネントがアプリケーションデータの特定の部分を管理しているかを追跡するのが困難な場合があります。このため、React チームはデータ操作のロジックを中央の場所に置くことを推奨しています。これを行う最も簡単な方法は、子コンポーネントにコールバックを渡すことです。また、Facebook で開発された Flux というアーキテクチャもあり、これには 独自のウェブサイト .
コンポーザブルコンポーネントの作成
多くの場合、状態のいくつかのピースまたはUIロジックのいくつかのピースを管理する大きなコンポーネントを書きたくなることがあります。可能であれば (そして無理のない範囲で)、大きなコンポーネントを、データまたは UI ロジックの単一のピースで動作する小さなコンポーネントに分割することを考慮すべきです。そうすることで、アプリケーションの拡張や移動がより簡単になります。
ミュータブルデータに注意
コンポーネントの状態を更新するのは
this.setState
への呼び出しによってのみ更新されるべきなので、ミュータブルデータに注意することは有用です。複数の関数(またはコンポーネント!)が同じtickでミュータブルオブジェクトを更新する可能性がある場合、これは二重に当てはまります。Reactは状態の変更をバッチ処理しようとするかもしれませんし、更新を失うかもしれません Eliseu Monarのコメントにもあるように、ミュータブルオブジェクトを変異させる前にクローンすることを検討してください。Reactには
不変性ヘルパー
があり、それを利用することができます。
もうひとつの選択肢は、変更可能なデータ構造を直接状態に保持することを一切見合わせることです。前述のFluxパターンは、この考えに対する興味深い試みです。
というReactのサイトに素晴らしい記事があります。
Reactで考える
という素晴らしい記事があり、アイデアやモックアップをどのようにReactアプリケーションに変換するかを説明しています。具体的な例として、あなたが提供したコードを見てみましょう。基本的に管理するデータは1つです。
container
要素の中に存在するコンテンツのリストです。UI に対するすべての変更は、そのデータに対する追加、削除、および変更によって表すことができます。
上記のような考え方を応用すると、最終的には以下のようなアプリケーションになるかもしれません。
/** @jsx React.DOM */
var Application = React.createClass({
getInitialState: function() {
return {
content: []
};
},
render: function() {
return (
<div className="container">
<span className="header">jQuery to React.js Header</span>
<button className="add_button"
onClick={this.addContent}>Add Element</button>
<button className="add_button"
onClick={this.timedAddContent}>Add Element in 3 Seconds</button>
{this.state.content.map(function(content) {
return <ContentItem content={content} removeItem={this.removeItem} />;
}.bind(this))}
</div>
);
},
addContent: function() {
var newItem = {className: "added_content", text: "Click to close"},
content = this.state.content,
newContent = React.addons.update(content, {$push: [newItem]});
this.setState({content: newContent});
},
timedAddContent: function() {
setTimeout(function() {
var newItem = {className: "timed_added_content", text: "Click to close"},
content = this.state.content,
newContent = React.addons.update(content, {$push: [newItem]});
this.setState({content: newContent});
}.bind(this), 3000);
},
removeItem: function(item) {
var content = this.state.content,
index = content.indexOf(item);
if (index > -1) {
var newContent = React.addons.update(content, {$splice: [[index, 1]]});
this.setState({content: newContent});
}
}
});
var ContentItem = React.createClass({
propTypes: {
content: React.PropTypes.object.isRequired,
removeItem: React.PropTypes.func.isRequired
},
render: function() {
return <span className={this.props.content.className}
onClick={this.onRemove}>{this.props.content.text}</span>;
},
onRemove: function() {
this.props.removeItem(this.props.content);
}
});
React.renderComponent(<Application />, document.body);
このコードの実行は このJSFiddle : http://jsfiddle.net/BinaryMuse/D59yP/
このアプリケーションは2つのコンポーネントで構成されています: トップレベルのコンポーネントである
Application
という配列を (その状態で) 管理するものです。
content
というコンポーネントと
ContentItem
というコンポーネントがあり、これはその配列から一つの項目のUIと動作を表します。
Application
's
render
メソッドは
ContentItem
要素を返します。
の中の値を管理するためのロジックは、すべて
content
配列内の値を管理するロジックはすべて
Application
コンポーネントで処理されます。
ContentItem
コンポーネントは
参照
への
Application
's
removeItem
というメソッドがありますが、これは
ContentItem
メソッドに委ねられます。これにより、状態を操作するためのすべてのロジックがトップレベルコンポーネントの内部に保持されます。
関連
-
[解決済み] 配列から特定の項目を削除するにはどうすればよいですか?
-
[解決済み] jQueryで要素が非表示になっているかどうかを確認するには?
-
[解決済み] jQueryでチェックボックスに "checked "を設定する
-
[解決済み] jQueryの「exists」関数はありますか?
-
[解決済み】別のウェブページにリダイレクトするにはどうすればいいですか?
-
[解決済み】jQueryでチェックボックスがチェックされているかどうかを確認するにはどうすればよいですか?
-
[解決済み】オブジェクトからプロパティを削除する(JavaScript)
-
[解決済み] サブドメインにまたがってlocalStorageを使用する
-
[解決済み] javascriptで文字列から関数を作成する方法はありますか?
-
[解決済み] Promise : then vs then + catch [重複].
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 文字列のn番目の出現箇所を取得するには?
-
[解決済み] URL/アドレスバーからJavascriptの関数を呼び出す
-
[解決済み] React js 親コンポーネントから子コンポーネントの状態を変更する
-
[解決済み] サブドメインにまたがってlocalStorageを使用する
-
[解決済み] javascriptで文字列から関数を作成する方法はありますか?
-
[解決済み] AJAX Mailchimp サインアップフォームの統合
-
[解決済み] JSHintの'+'前の改行不良の説明
-
[解決済み] jQueryを使用して、すべてのクリックイベントハンドラを削除するにはどうすればよいですか?
-
[解決済み] <ng-content>が空かどうかを確認する方法は?(これまでのAngular 2+で)
-
[解決済み] HTML要素にスクロールバーがあるかどうかをチェックする