ReactJSのリモートAJAXコンポーネント

ここでは、反応アプリケーション全体とは別に、リモート反応コンポーネントをロードしてレンダリングする方法について説明します! この問題をどのように解決したかを示します。 1年後、 react-remote-component-demo以外の同様のソリューションは見つかりません。









Reactでプロジェクトを開発するとき、タスクが設定されました。Reactの1ページのアプリケーションが追加コンポーネントをAJAXにロードして表示する必要があります。これらのコンポーネントは、アプリケーション自体に関係なくサーバー上で修正する必要がありました。







アプリケーションの構造は次のように簡略化されています。左側にコンポーネントのリストがあり、そのうちの1つをクリックすると、AJAXを介してリモートコンポーネントがロードされ、その詳細ビューが表示されます。







なぜなら 構築時にWebpackを使用しました。何かをグーグルで検索する最初の試みはrequire.ensureの使用につながりました







私の場合、これは不可能であることが判明しました。 Webpackのコンパイル時には、リモートコンポーネントの数はわかりません。コンポーネントが特定のフォルダーから静的に配布されるか、サーバーがデータベースからコンポーネントを配布することしかわかりません。







したがって、 CommonsChunkPluginを使用してwebpackに通知することは不可能であることが判明したため、これらの入力ファイルはそこに個別に配置する必要があります。 ファイルの数はわかりません。







合計で、reactアプリケーション自体はwebpackを使用して収集され、リモートコンポーネントは個別に準備されます(この場合、reactアプリケーション自体から削除されているため、このような定義を与えました)。







また、ES6でリモートコンポーネントを美しく書きたいと思いました。 そのため、リモートコンポーネントのコンパイル加えてBabelを使用する必要がありました。







試行錯誤を通じて、リモートコンポーネントをコンパイルすることができました。







コンポーネントは次のようになりました。







class CMP extends React.Component { constructor(props) { super(props); } render() { return <div> <div>Hello from <strong>FIRST</strong> remote component!</div> <div>{this.props.now}</div> </div> } } module.exports = CMP;
      
      





これは、ソースリモートコンポーネント全体のリストであり、 import ... from ...



または... = require(...)



node_modules



からのnode_modules



... = require(...)



でないため、機能しません。 さらに、 module.exports



最後にあります。







ES6 1.jsx



には、バブルの助けを借りてES5 1.js



でコンパイルできるコンポーネントがあります。







コンパイル後、 1.js



コンポーネントが1.js



たテキストファイルが完成し1.js









1.js
 "use strict"; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var CMP = function (_React$Component) { _inherits(CMP, _React$Component); function CMP(props) { _classCallCheck(this, CMP); return _possibleConstructorReturn(this, (CMP.__proto__ || Object.getPrototypeOf(CMP)).call(this, props)); } _createClass(CMP, [{ key: "render", value: function render() { return React.createElement( "div", null, React.createElement( "div", null, "Hello from ", React.createElement( "strong", null, "FIRST" ), " remote component!" ), React.createElement( "div", null, this.props.now ) ); } }]); return CMP; }(React.Component); module.exports = CMP;
      
      





このファイルは、すでに静的に、またはデータベースから指定できます。







このファイルを反応アプリケーションにロードし、それからコンポーネントを作成し、レンダリングするために残ります。







これを行うコンポーネントはRemote



と呼ばれます。 リストを表示するには、 List



呼び出しましょう。

ロジックは次のようなものです。Listはclick



ユーザーイベントをリッスンし、どのリスト項目がクリックされたかを判断します。したがって、このcomponent



プロパティをprops



としてRemote



に渡しcomponent





Remote



内部Remote



は、 componentWillReceiveProps()関数を使用しました。 そのため、プロパティが変更されたと判断し、転送されたリモートコンポーネントの詳細ビューをレンダリングする必要があります。 これを行うには、コンポーネントキャッシュにあるかどうかを確認し、ない場合はロードします。







リモートコンポーネントを読み込むことは難しくありません(わかりやすくするために、 XMLHttpRequestの上位レベルのラッパーを使用しています)。

すべての魔法は次に起こります:







  ajax.load('/remote/' + requiredComponent) .then((str_component) => { let component; try { let module = {}, Template = new Function('module', 'React', str_component); Template(module, React); component = React.createFactory(module.exports); } catch (e) { console.error(e); } })
      
      





ロードされた行/コンポーネントから、テンプレート関数をnew Function()



ます。 入力パラメーターとして、2つの文字列変数module



React



を定義します。 このテンプレートTemplate(module, React)



「呼び出し」 Template(module, React)









新しいmodule = {}



オブジェクトを作成し、それを最初の場所に渡し、reactモジュールを2番目の場所に渡します。







したがって、リモートコンポーネント内で記述した内容を思い出すと、次のようになります。







 ... extends React ...
      
      





そして







 module.exports = ...
      
      





関数/テンプレートを「呼び出す」とき、これらの2つの変数を渡します。エラーがないはずです。 これら2つの変数を定義しました。







その結果、オブジェクトmodule = {}



結果はexports



プロパティに割り当てられます。 これが、 module.exports



React



を使用して、コンポーネントのコンパイル段階でエラーをバイパスするという2つの問題を解決する方法です。 そして、それらを入力パラメーターとして定義したので、ブラウザーで既にテンプレートを「実行」します。







コンポーネントcomponent = React.createFactory(module.exports)



を作成し、レンダリングします。







  render() { let component = ...; return <div> {component ? component({ now: Date.now() }) : null} </div> }
      
      





コンポーネントを呼び出すときに、 props



として表示されるcomponent({ now: Date.now() })



パラメーターを渡すことができます。







リモートコンポーネントはネイティブのように動作します!







要求されたアプリケーションのコードは、 react-remote-component githubに投稿されました:

開始するには、次を実行します。







npm install



すべてのモジュールをインストール







npm run build-cmp



、リモートコンポーネントをdist/remote



コンパイルします







npm run server-dev



webpack devサーバーnpm run server-dev



起動します。これにより、アプリケーション全体がRAMに収集され、そこから配布され、削除されたコンポーネントが静的に配布されます。







ブラウザでhttp:// localhost:8099 /に移動します








All Articles