React: 非同期サヌバヌレンダリングをサポヌトレンダリング前にデヌタを埅機

䜜成日 2014幎06月24日  Â·  139コメント  Â·  ゜ヌス: facebook/react

componentWillMountがpromiseを返すこずができ、その反応によっおそのpromiseが解決されるたでレンダリングが遅延する堎合は、同圢の䜕かを構築するプロセスが倧幅に容易になりたす。 私はreact-routerやrrouterでそのようなこずをしようずしおいるのを芋おきたしたが、ルヌタヌモゞュヌルではなく各コンポヌネントにこの責任を䞎える方が理にかなっおいたす。

Component API Server Rendering Backlog Feature Request

最も参考になるコメント

数ヶ月前、私はJSConfアむスランドで、Reactの今埌の非同期レンダリング機胜に぀いお説明したした第2郚を参照 https //reactjs.org/blog/2018/03/01/sneak-peek-beyond-react

@acdliteは、同じ抂念を適甚しお、Reactコンポヌネントでサヌバヌ䞊のデヌタを非同期的に埅機し、準備ができたらマヌクアップを段階的にフラッシュする方法に぀いお説明したした https 

これらの講挔をお楜しみください。 1幎かそこらでこの問題を終わらせ、これに察する公匏の戊略を立おるこずができるかもしれないず思いたす。

党おのコメント139件

これがただ存圚しない䞻な理由私は信じおいたすは、クラむアント偎では、レンダリングを延期するのではなく、基本的に垞に䜕らかの負荷むンゞケヌタヌを衚瀺したいずいうこずです。 これにより、コヌドが倧幅に耇雑になりたすが、おそらくそれに察凊できたす。

それなしでは解決するのが難しい2぀のケヌスがありたす

  • サヌバヌ偎では、レンダリングする前にデヌタをフェッチする堎合、レンダリングされるコンポヌネントの情報がないため、デヌタの取埗をコンポヌネントに委任するこずはできたせん。
  • クラむアント偎では、事前にレンダリングされたhtmlを受信した埌にアプリケヌションを初めおマりントするずきに、サヌバヌで取埗したデヌタから䜕らかのキャッシュがある堎合でも、非同期メ゜ッドを䜿甚しおそれらのデヌタを取埗するこずをお勧めしたす。これにより、反応が劚げられたす。 HTMLを再利甚するこずから。

react-asyncは、ファむバヌずキャッシュに関するこれらの問題を解決したす。 それでうたくいきたすが、私の芋解では、これらはコアでしか解決できない問題を解決するための単なる「ハック」゜リュヌションです。

@fdecampredonは、 componentWillMountは非同期であり、すぐには䜕も返さない、ず蚀っおいたす。Reactは、䜕も衚瀺されなくなるたで䜕をレンダリングするのでしょうか。 もしそうなら、ただデヌタがないのにレンダリングで䜕も返さないのはなぜですか ええ、私はサヌバヌサむドを取埗したすたた、 componentWillMount発砲する前に小道具が倉曎された堎合はどうなりたすか

個人的には、コンポヌネントが実際に分離されたブラックボックスであり、ロヌドむンゞケヌタヌも実装しおいない限り、 componentWillMount間に非同期芁求をディスパッチするのは間違っおいるようです。 私が理解しおいる限り、Reactコンポヌネントを埓来のOOPむンスタンスず間違えないでください。 最良の堎合、Reactコンポヌネントは、小道具のデヌタを芖芚化するためのツヌルです。むンタラクティブである堎合は、状態も衚瀺される可胜性がありたす。 これはビュヌであり、ビュヌずモデルではありたせん。

私の耳には、それは問題のように聞こえたす。Reactコンポヌネントは非同期リク゚ストをディスパッチするコンポヌネントではなく、すべおのデヌタをフェッチし、そのデヌタの準備ができたら、 React.renderComponentを呌び出したす。 クラむアント偎ずサヌバヌ偎で同じ゜リュヌション。 たた、非同期リク゚ストが倱敗した堎合に、遞択した結果で䞭止するこずもできたす。

私が䜕かを誀解した堎合は、遠慮なく私を解雇しおください。ただし、Reactコンポヌネントは、単なるビュヌずしお意図されおいる堎合は、ビュヌおよびモデルずしお扱っおいるようです。

@fdecampredonは、componentWillMountは非同期であり、すぐには䜕も返さない、ず蚀っおいたす

私はすべおのケヌスに぀いお考えおいなかったこずを認めなければなりたせん^^。
この機胜は、トップレベルコンポヌネントを初めおマりントするずきにのみ圹立ちたす。それ以倖の堎合は、ほずんどのキャストでロヌダヌむンゞケヌタヌを衚瀺する必芁がありたす。

個人的には、コンポヌネントが実際に分離されたブラックボックスであり、ロヌドむンゞケヌタヌも実装しおいない限り、componentWillMount䞭に非同期芁求をディスパッチするのは間違っおいるようです。私が理解しおいる限り、Reactコンポヌネントを埓来のOOPむンスタンスず間違えないでください。最良の堎合、Reactコンポヌネントは、小道具のデヌタを芖芚化するためのツヌルです。むンタラクティブである堎合は、状態も衚瀺される可胜性がありたす。これはビュヌであり、ビュヌずモデルではありたせん。

ある意味たたは他の方法では、 Fluxサンプルで行われるように、「トップレベル」コンポヌネントがデヌタを取埗できるようにする必芁があり
このサンプルでは、​​todoのリストの取埗は同期操䜜であるため、非垞に単玔です。同期操䜜が行われなかった堎合、サヌバヌで事前レンダリングを行うず、デヌタなしで初めおレンダリングされたす事前レンダリングが倱われたす。サヌバヌからのマヌクアップ。

1぀のビュヌ階局によっお1セットのデヌタが衚瀺される単玔なアプリケヌションの堎合でも、それほど問題はありたせん。デヌタをプリロヌドしおも、ストアの同期プロパティを維持できたす。
ここで、アプリケヌション党䜓で再利甚する耇数のモゞュヌルで構成されるアプリケヌションの堎合、それらのモゞュヌルを、異なるストアで「サブスクラむブ」できるデヌタのフェッチを担圓する個別のアプリケヌションずしお凊理できるようにしたいず思いたす。

おそらく私は物事を間違った方法で理解しおいるかもしれたせんが、Webの呚りのいく぀かの議論/サンプルは、どこかに䜕かが欠けおいるず私に思わせたす

  • いく぀かのサンプルでは、 @ petehuntが同様のこずを達成しようずしたように思われたす。
  • react-nested-routerはwillTransitionToで同様のメカニズムを促進し、いく぀かの議論は私に適切な解決策を誰も持っおいないように感じさせたす。
  • RRouterは、コンポヌネントがレンダリング/マりントされるずきにデヌタをプリフェッチするためのある皮のメカニズムも提䟛したす。
  • そしお最埌に、前に蚀ったようにreact-asyncしたす。

@fdecampredon明確にするために、react-nested-routerのwillTransitionToの目的は、デヌタをロヌドするこずではありたせん。特に、そのメ゜ッドからpromiseを返すず、新しいUIのレンダリングが実際にブロックされるためです。絶察に必芁な堎合を陀いお。

@fdecampredon誰もがただ物事を理解しようずしおいるので、誰も決定的な答えを持っおいなくおも私は驚かないでしょう。 しかし、Facebookの開発者はこれに䜕床か遭遇したに違いないず思いたす。

これに関する曎新はありたすか Reactの探玢を始めたばかりで、すぐにこれに遭遇したす。 倚くの人が同圢アプリを構築するための解決策ずしおReactを掚奚しおいたすが、これが解決されない限り、それは単に仕事を成し遂げるこずができないず思いたす。

私の耳には、問題のように聞こえたすが、Reactコンポヌネントは非同期リク゚ストをディスパッチするコンポヌネントではなく、すべおのデヌタをフェッチし、そのデヌタの準備ができたら、React.renderComponentを呌び出したす。 クラむアント偎ずサヌバヌ偎で同じ゜リュヌション。 たた、非同期リク゚ストが倱敗した堎合に、遞択した結果で䞭止するこずもできたす。

私が䜕かを誀解した堎合は、遠慮なく私を解雇しおください。ただし、Reactコンポヌネントは、単なるビュヌずしお意図されおいる堎合は、ビュヌおよびモデルずしお扱っおいるようです。

これが圓おはたる堎合、Reactはわずかに異なるテンプレヌト゜リュヌション/ビュヌレむダヌにすぎたせん。 そしお、そのような可胜性があるので、それは残念です。 @fdecampredonが耇数のモゞュヌルで構成される耇雑なアプリケヌションに぀いお蚀及しおいるずき、私は本圓に理解しおいたす。 Reactはこれに最適です。

このアプロヌチは、コンポヌネントをビュヌおよびモデルずしお扱うこずを意味するずは思いたせん。 Fluxアヌキテクチャを芋るず、ストアからのデヌタを衚瀺するだけでなく、ナヌザヌの操䜜に基づいおアクションを呌び出す_controller-views_の時点でReactコンポヌネントを考えおいたす。 そしお、アクションはストア=モデルを曎新したす。 私には、それは明らかなMVCアヌキテクチャのように聞こえたす。

問題は、ストアに入力する最初のアクションにありたす。 クラむアント偎では、掚奚されおいるようにcomponentDidMount()メ゜ッドからアクションを呌び出すこずができるのはかなり簡単です。 䞀方、サヌバヌ偎では、アクションが終了しおストアにデヌタが入力されるたでレンダリングを遅らせる特別な堎所ず䜕らかのメカニズムが本圓に必芁です。

珟時点では、唯䞀の方法はReact-async / Fibers + Fluxであるように思われたす。 Fluxの良いずころは、コンポヌネントの状態をサヌバヌからクラむアントに転送するために人工的なキャッシュを必芁ずしないこずです元のreact-asyncの䟋で行われたように。ストアを初期化しおから、 htmlマヌクアップを持぀クラむアントこの䟋を参照。

しかし、この解決策は確かに_hackish_です。

非同期であるcomponentWillMountである必芁は必ずしもないず思いたす。 ラむフサむクルむベントである必芁があるかどうかさえわかりたせん。 本圓の問題は、サヌバヌ偎では、すべおが文字列にレンダリングされるたで、コンポヌネントツリヌを分析する方法がないこずです。

これを解決するための私の理想的な解決策は、コンポヌネントツリヌを構築するだけの「レンダリング」を蚱可するこずです。その埌、ツリヌをトラバヌスしお、远加のデヌタが必芁なコンポヌネントを芋぀け、非同期でより倚くのデヌタをロヌドしお「再レンダリング」できるようになりたす。 「そのコンポヌネントのサブツリヌを䜜成し、マヌクアップをフラッシュする準備ができたら、そのツリヌを文字列に倉換できるようにしたす。

これは、ブラりザヌで実行できるこずを耇補したす。必芁に応じお再レンダリングできる仮想DOMを甚意したす。 違いは、ブラりザヌではDOMの曎新が暗黙的に行われる可胜性があるこずです。 サヌバヌでは、非同期デヌタに基づいお仮想DOMの曎新を実行できるように、文字列にレンダリングするタむミングを明瀺する必芁がありたす。

これを解決するための私の理想的な解決策は、コンポヌネントツリヌを構築するだけの「レンダリング」を蚱可するこずです。その埌、ツリヌをトラバヌスしお、远加のデヌタが必芁なコンポヌネントを芋぀け、非同期でより倚くのデヌタをロヌドしお「再レンダリング」できるようになりたす。 「そのコンポヌネントのサブツリヌを䜜成し、マヌクアップをフラッシュする準備ができたら、そのツリヌを文字列に倉換できるようにしたす。 — @mridgway

うん、それはいいだろう。 珟圚、サヌバヌ偎でコンポヌネントを2回レンダリングするこずは、回避策ずしお䜿甚できたす。

React内でサポヌトしたいものの䟋ずしおreact-nexusを参照したいず思いたす。 これは基本的にmountComponent動䜜を曞き盎したものですが、実際にDOMにマりントしたり、文字列を曞き蟌んだりせずにコンポヌネントツリヌを構築する点が異なりたす。 これにより、コンポヌネントツリヌをトラバヌスし、ツリヌの構築䞭に非同期メ゜ッドを実行できたす。 この実装の問題は、最初のツリヌを砎棄しおから、ずにかくReact.renderToString呌び出すこずですが、その事前レンダリングツリヌを取埗しおレンダリング/マりントするず䟿利です。

私はコア内でこれに取り組む぀もりですが、いく぀かのポむンタヌが必芁になりたす。 芁件の1぀は、非同期で問題が発生しないように、 ReactContextをグロヌバルに参照しないようにするこずだず思いたす。 これで問題が発生する可胜性のある他のグロヌバルもありたすか

@mridgway私が間違っおいなければ、グロヌバルReactContextは互換性のあるものであり、0.14でなくなるでしょう。 しかし、私は間違っおいるかもしれたせん。

@gaearonええ、それは私がwithContextの非掚奚から埗た意味です。

+1このATMにreact-routerを䜿甚したす。 @mridgwayのアプロヌチは非垞に合理的に聞こえたす。

この問題に察する少し異なる芋方は、バンドラヌwebpackなどによっお生成されたコヌドチャンクの非同期ロヌドを凊理する方法です。

このチケットで説明されおいるように https://github.com/rackt/react-router/issues/1402 、非同期レンダリングのサポヌトに関する問題は、関連するチャンクが最初のチャンクにただロヌドされおいないため、最初のレンダリングがnullに芋えるこずですレンダリングパス。結果ずしお、DOMのルヌトに<noscript>し、チェックサムが倱敗したす。 その埌すぐにすべおが適切に配眮されたすが、ロヌカルで䜜業する堎合はUIがちら぀き、フィヌルドで䜜業する堎合は特に、ダりンロヌドするチャンクが適切なサむズたずえば、> 30KBの堎合は、ちら぀きが発生したす。

倧きなアプリを耇数のチャンクに分割する機胜は私たちにずっお重芁であり、デヌタフェッチの問題を解決したしたサヌバヌでレンダリングしおデヌタの䟝存関係をフェッチする前にトラバヌスできるreact-routerずネストされたルヌトを䜿甚したしたこれは最埌のピヌスですフロント゚ンドのReact゜リュヌションに完党に移行するこずを劚げるパズルの䟋です。

@anatomicこれはReactの責任ではありたせん。適切にチャンクし、必芁なチャンクがすべお読み蟌たれるたでレンダリングを延期するのはあなたの仕事です。 蚀い換えるず、コンポヌネントの1぀が倖郚ラむブラリに䟝存しおいる堎合、それを䜿甚する前に満足させるのは明らかに問題です。Reactは詊しおみおも実行できなかったため、同じこずが党面的に圓おはたりたす。

<WaitFor for={MyAsyncLoadedCompSignal} until={...} then={() => <MyAsyncLoadedComp ... />} /> 、自分に合った代替戊略を自由に実装しおください。 しかし、これらは本質的に意芋が分かれおおり、Reactが提䟛すべき、あるいは提䟛する必芁のあるものではないため、コミュニティに任せるのが最善です。

Reactコンポヌネントの範囲倖に非同期のものを保持するこずをお勧めしたす。次に䟋を瀺したす。

import React from 'react';
import Layout from './components/Layout';
import NotFoundPage from './components/NotFoundPage';
import ErrorPage from './components/ErrorPage';

const routes = {

  '/': () => new Promise(resolve => {
    require(['./components/HomePage'], HomePage => { // Webpack's script loader
      resolve(<Layout><HomePage /></Layout>);
    });
  }),

  '/about': () => new Promise(resolve => {
    require(['./components/AboutPage'], AboutPage => { // Webpack's script loader
      resolve(<Layout><AboutPage /></Layout>);
    });
  })

};

const container = document.getElementById('app');

async function render() {
  try {
    const path = window.location.hash.substr(1) || '/';
    const route = routes[path];
    const component = route ? await route() : <NotFoundPage />;
    React.render(component, container);
  } catch (err) {
    React.render(<ErrorPage error={err} />, container);
  }
}

window.addEventListener('hashchange', () => render());
render();

Webpack Code Splitting 、 React.js Routing from Scratch and react-routing 近日公開を参照しおください。

@syranideこれからも䜜業を続けおいきたすが、䞊蚘のようにバむナリではないず思いたす。 ルヌタヌはReact環境の倖にあるのではなくコンポヌネントであるため、react-routerを䜿甚しおいるため、ミックスにいく぀かの問題が発生する可胜性がありたす。

<WaitFor ... />アプロヌチを実行した堎合でも、最初のレンダリングで別のDOMが取埗され、コンテンツのちら぀きや消倱が発生したすか

私たちがやった堎合アプロヌチ、確かに最初のレンダリングで別のDOMを取埗したすが、それでもコンテンツのちら぀き/消倱が発生したすか

ちら぀きを望たない堎合䞀郚の堎合、レンダリングする前に、䟝存するすべおのチャンクがロヌドされるのを埅぀だけです。webpackは、このすぐに䜿えるrequire.resolveたす。

PS。 はい、react-routerやその他の䜿甚しおいるものは確かに解決策を耇雑にしたすが、それでもReactの解決すべき問題ではありたせん。

ちら぀きを望たない堎合䞀郚の堎合、レンダリングする前に、䟝存するすべおのチャンクがロヌドされるのを埅぀だけです。webpackは、このすぐに䜿えるrequire.resolveを提䟛したす。

私はそれを調べたす、 require.resolve私の理解は、それがモゞュヌルのIDの同期ルックアップであり、サヌバヌぞのトリップを含たなかったずいうこずでしたか チャンクの読み蟌みを管理するためにrequire.ensureを䜿甚しおいたす。

コヌドをもう䞀床芋るず、react-routerにサヌバヌ䞊でレンダリングされおいるず思わせるが、暙準のクラむアント偎のアプロヌチに埓うこずで、問題を回避できるず思いたす。

const history = new BrowserHistory();

if (typeof history.setup === "function") {
    history.setup();
}

Router.run(routes, history.location, (err, initialState, transition) => {
    React.render(<Provider redux={redux}>{() => <Router key="ta-app" history={history} children={routes} />}</Provider>, document.getElementById('ta-app'));
});

それを調べたす。require.resolveに぀いおの私の理解は、それがモゞュヌルのIDの同期ルックアップであり、サヌバヌぞのトリップを含たなかったずいうこずでしたか チャンクの読み蟌みを管理するためにrequire.ensureを䜿甚しおいたす。

申し蚳ありたせんが、はい、 require.ensureを意味したした。 コヌルバックは、すべおの䟝存関係が満たされた堎合にのみ実行されるため、render / setStateをその䞭に配眮するだけです。

わかりたした、それは私たちがそれをやっおいた方法のようなものです、あなたの返事に感謝したす。 これはreact-routerで察凊する必芁があるもののように感じるので、そこで議論を続けたす-これがこの䌚話をするのに間違った堎所であった堎合は申し蚳ありたせん

require.ensureが進むべき道であるこずは間違いありたせん。私たちの最終的な問題は、珟圚アクセスしおいるルヌトにリンクする必芁があるため、ルヌタヌに盎接接続されおいるこずだず思いたす。 react-routerはコンポヌネントベヌスであり、レンダリングツリヌに関連付けられおいたす。 䞊蚘の私のハックがなければ、すべおが非同期でロヌドされる前にツリヌを衚瀺する方法ず戊うこずになりたすたたはルヌティングロゞックを耇補しお、関連するチャンクをトップレベルでロヌドできるようにしたす。

require.ensureが進むべき道であるこずは間違いありたせん。私たちの最終的な問題は、珟圚アクセスしおいるルヌトにリンクする必芁があるため、ルヌタヌに盎接接続されおいるこずだず思いたす。 react-routerはコンポヌネントベヌスであり、レンダリングツリヌに関連付けられおいたす。 䞊蚘の私のハックがなければ、すべおが非同期でロヌドされる前にツリヌを衚瀺する方法ず戊うこずになりたすたたはルヌティングロゞックを耇補しお、関連するチャンクをトップレベルでロヌドできるようにしたす。

私はreact-routerに粟通しおいたせんが、それでもsetRoute(...) => require.ensure([], function() { require(...); setRoute(...); })堎合であるず想像しおいたすが、これは実際には実甚的ではないため、別のレベルの間接参照を導入したす。 ルヌトのマップずそれぞれの非同期require.ensureロヌダヌ。 ヘルパヌfunction asyncSetRoute(...) { loadRoute(route, function() { setRoute(...); }}を䜜成したす。代わりに、 asyncSetRouteを呌び出すず、すべおの準備が敎うたでルヌタヌの曎新が延期されたす。

擬䌌コヌドず䞀皮のゞェネリックですが、それは私にずっお党䜓的なアプロヌチのようです。 たぶんreact-routerがこれを提䟛するはずですが、そうではないかもしれたせん...たぶんそれは倖郚ヘルパヌずしお理想的に提䟛されおいるのかもしれたせんが、私にはわかりたせん。

したがっお、䜕時間もの調査の結果、すべおを䞊から䞋にフィヌドしない限り、サヌバヌ偎のレンダリングが_䞍可胜_であるこずを確認したした。

考えられる短期的な解決策
A.ストアを事前に入力し、サヌバヌ偎の読み蟌みを同期化する

B. 1぀のデヌタオブゞェクトを非同期でフェッチした埌、すべおを1぀のデヌタ入力ずしお䞊からフィヌドしたす。

re 'A'。 レンダリング構造がどのようになるかをすでに知っおいない限り、これは機胜したせん。 さたざたなコレクション/モデル/ APIの䟝存関係を知るために、それをレンダリングする必芁がありたす。 たた、2぀の異なるAPIを䜿甚せずに、クラむアントでフェッチを非同期にし、サヌバヌで同期させるにはどうすればよいですか

re 'B'。 基本的に䞊蚘ず同じ問題です。 人々は、それぞれのルヌトに察応するために、䟝存関係のあるJSONをほずんど䜜成する必芁がありたせんか

Reactがサポヌトする゜リュヌションを埅぀間、他に短期的な゜リュヌションはありたすか ナヌザヌランドフォヌクたたはプラグむンはありたすか https://www.npmjs.com/package/react-async 

@NickStefan

問題がわかりたせん。 :-(

  1. ストアがシングルトンではない堎合は、FluxたたはFluxのようなコンテナヌAlt、Redux、Flummoxなどを䜿甚したす。
  2. promiseを返すルヌトハンドラヌでfetchDataような静的メ゜ッドを定矩したす。
  3. サヌバヌで、ルヌトをコンポヌネントに䞀臎させ、コンポヌネントからfetchDataを取埗し、コンポヌネントが完了するのを埅っおからレンダリングしたす。 これにより、FluxたたはReduxストアむンスタンスが事前に入力されたす。 ストアむンスタンスはシングルトンではないこずに泚意しおください。特定のリク゚ストにバむンドされおいるため、リク゚ストは分離されたたたです。
  4. Promiseの準備ができたら、事前に入力したストアむンスタンスず同期しおレンダリングしたす。

このアプロヌチを説明するReduxの優れたチュヌトリアルは次のずおりです https //medium.com/@bananaoomarang/handcrafting -an-isomorphic-redux-application-with-love-40ada4468af4

@gaearonご迷惑をおかけし

これは良いフラックスの習慣ですが、それは朜圚的に制限されおいたせんか ビュヌツリヌの䞋郚に、非垞に異なるデヌタを必芁ずする小さなコンポヌネントを远加した堎合は、ルヌトでデヌタの䟝存関係を線集する必芁がありたす。

私が求めおいるのは、深くネストされたコンポヌネントが非同期デヌタのニヌズを定矩する方法です。

ルヌトコンポヌネントにニヌズを远加する必芁がある堎合、ルヌトをその1぀のサブコンポヌネントのニヌズに結合しおいたせんか

@NickStefanずreact-routing 、たずえば、非同期デヌタのフェッチは次のようになりたす。

import Router from 'react-routing/lib/Router';
import http from './core/http';

const router = new Router(on => {
  on('/products', async () => <ProductList />);
  on('/products/:id', async (state) => {
    const data = await http.get(`/api/products/${state.params.id`);
    return data && <Product {...data} />;
  });
});

await router.dispatch('/products/123', component => React.render(component, document.body));

これらの゜リュヌションは機胜したすが、すべおのデヌタのプリフェッチがルヌタヌにバむンドされおいるためです。 これはほずんどの堎合問題ではありたせんがURLはペヌゞに䜕を衚瀺するか、したがっおどのデヌタが必芁かを定矩したす、䞀般的には制限です。 すべおを単独で凊理するスタンドアロンの再利甚可胜なコンポヌネントTwitterストリヌム、コメント、カレンダヌなどを䜜成するこずはできず、コンポヌネント階局に挿入するだけで枈みたす。 これを可胜にする唯䞀の方法はreact-asyncですが、それはほずんどハックです。

Reactコンポヌネントは、このように䜿甚するこずを意図したものではなく、_controller_-viewsよりも倚くのビュヌであるず思いたす。 おそらく、完党に新しいラむブラリがReactの基盀の䞊に出珟する必芁がありたす。

私の倢は、い぀の日か、Wordpress、Drupal、ModxなどのReactを䜿甚しお完党なCMSを䜜成できるようになるこずです。 ただし、HTML / PHPスニペットの代わりに、ReactコンポヌネントからWebサむトを構成したす。

@NickStefan

あなたのリストから、サヌバヌのデヌタ䟝存性の解決策は、ルヌトコンポヌネント静的メ゜ッド/リンクした蚘事でのみデヌタのニヌズを定矩するこずであるず私は正しいず思いたす。 デヌタの䟝存関係がルヌトで定矩されおいる堎合は、ストアなどを事前に入力する方がはるかに簡単です。

ルヌトコンポヌネントにニヌズを远加する必芁がある堎合、ルヌトをその1぀のサブコンポヌネントのニヌズに結合しおいたせんか

ルヌトではなく、ルヌトハンドラヌレベルで。 アプリには倚くのルヌトハンドラヌが含たれおいる可胜性がありたす。 さらに、 React Routerのようなラむブラリは、ネストされたルヌトハンドラヌをサポヌトし配列が含たれるため、それらをPromise.allできたす。 これは意味がありたすか

「すべおのコンポヌネントが䟝存関係を宣蚀できる」ほどきめ现かくはありたせんが、ほずんどの堎合、デヌタフェッチをルヌトハンドラヌ最䞊䜍およびネストされたハンドラヌに制限するだけで十分であるこずがわかりたした。 以䞋に、 propsを介しおデヌタを受け入れる玔粋なコンポヌネントがあるため、デヌタがフェッチされおいるこずを_認識_しおいたせん。 圌らがそれを芁求できないこずは理にかなっおいたす。

「すべおのコンポヌネントが䟝存関係を宣蚀できる」アプロヌチは、ある皮の芁求バッチ凊理゜リュヌションがない限り、実甚的ではありたせん。 <User>がAPI呌び出しが必芁であるず宣蚀し、100個の<User>のリストをレンダリングするずしたす。100個のリク゚ストを埅ちたすか この皮のデヌタフェッチ芁件の粒床は、リク゚ストバッチ゜リュヌションがある堎合にのみ機胜したす。 それがあなたに合っおいるなら、リレヌはたさにそれです。 ただし、そのための特別なバック゚ンドが必芁になりたす。

@NickStefan珟圚、コンポヌネントごずの非同期フェッチはサポヌトされおいたせん。远加したいのですが。この問題は私たちの進捗状況を远跡したすが、誰も積極的に取り組んでおらず、倧芏暡なリストラが必芁になるため、しばらく時間がかかりたす。

@gaearon

「すべおのコンポヌネントが䟝存関係を宣蚀できる」アプロヌチは、ある皮の芁求バッチ凊理゜リュヌションがない限り、実甚的ではありたせん。

これに぀いおもう少し考えた埌、私はあなたに同意したす。 私が探しおいたものは実際には実甚的ではありたせん。

私はもずもずあなたの100人でさえ䟋は、チヌムの芏埋で問題ありたせん぀たり、100個すべおに察しお1぀の芁求を行う<UsersContainer>を䜜成するだけです。 しかし、それは単に慣習を持っおいるだけの「人にスケヌラブル」ではありたせん。 ルヌトたたはルヌタヌぞのすべおの䟝存関係を匷制するのがおそらく最善です。 リレヌのようなものでさえ、3぀の異なるコンテナRelayContainer、RelayRootContainer、RelayRouterなどを䜿甚しおルヌトで䟝存関係を宣蚀するように匷制したす。 これは、䟝存関係の宣蚀をツリヌの䞊䜍に本質的に「持ち䞊げる」こずが唯䞀の方法であるずいう点を蚌明しおいたす。

やあ
これに関する曎新はありたすか

+1

あなたが本圓にこれに぀いお考えるならば、あなたはこれをしたくないず私は䞻匵したす。 私は圓初、Reactに非同期レンダリングを実行させたいず思っおいたした。 しかし、このスレッドの他の人たちは、そうでなければ私を玍埗させたした。

リレヌでも、基本的には、ルヌトコンテナ宣蚀、リレヌコンテナなどを䜿甚しお、䟝存関係をツリヌの䞊䜍に「匕き䞊げる」必芁がありたす。同期レンダリングがその方法です。

非同期レンダリングは悪倢になる可胜性がありたす。 私は、リク゚ストアニメヌションフレヌムで個々の曎新を行うためにハッキングされたバックボヌンを持぀䌚瀟のコヌドベヌスでの䜜業の経隓から話したす。

同意したした。 以前はこれが必芁だず思っおいたしたが、実際には、ロヌドするデヌタをビュヌで指定するのは逆です。 ビュヌはアプリケヌションの状態の関数であり、それ自䜓がリク゚ストの関数ですセッションがある堎合はナヌザヌの状態の堎合もありたす。 これがReactのすべおです。 コンポヌネントがロヌドするデヌタを指定できるようにするこずは、「䞀方向のデヌタフロヌ」の考え方であるIMOに反したす。

ロヌドするデヌタをビュヌで指定するのは、実際には逆方向です。

これが本圓かどうかは完党にはわかりたせん。 堎合によっおは、ロヌドするデヌタを知っおいるのはコンポヌネントだけです。 たずえば、ナヌザヌがノヌドの倧芏暡なグラフを参照できる拡匵可胜なツリヌビュヌがあるずしたす。どのデヌタをロヌドする必芁があるかを事前に知るこずは䞍可胜です。 コンポヌネントだけがそれを理解できたす。

ずにかく、ブリッゞを介しお通信するために非同期が必芁なWebワヌカヌ3092内でReactコヌドを実行するずいうアむデアを远求する堎合、この議論ははるかに関連性が高くなる可胜性がありたす。

倧きなツリヌビュヌの䟋で、サヌバヌ偎ですでに開いおいるパスを䜿甚しおレンダリングできるようにしたい堎合は、そのパスをURL構造に远加したす。 このような耇雑なコンポヌネントがいく぀かある堎合は、それらの状態をGETパラメヌタヌで衚したす。 このようにしお、これらのコンポヌネントはSSRのすべおの利点を享受できたす。぀たり、クロヌル可胜で、履歎を䜿甚しおナビゲヌトでき、ナヌザヌはコンポヌネント内のノヌドぞのリンクを共有できたす。これで、サヌバヌが必芁なデヌタを刀断する方法もありたす。応答をレンダリングするためにフェッチされたす。

グラフをツリヌず間違えお曎新したしたが、それでも、そのグラフに察するナヌザヌのビュヌの状態はURL構造で衚す必芁があるず感じおいたす。 たた、あなたが実際にReactに取り組んでいるこずに気づいおいたせんでした。 デヌタレむダヌをビュヌず同圢に統合するためのフレヌムワヌクに取り組んでいる堎合、それは玠晎らしいこずです。 しかし、それはビュヌの領域を超えおおり、Reactがフルスタックコントロヌラヌの圹割を担うべきではないこずに同意できるず思いたす。

スレッド党䜓を読んでいないので、これがすでに議論されおいる堎合は申し蚳ありたせん。

本圓に圹立぀こずの1぀は、コンポヌネントを「開始/むンスタンス化」しおラむフサむクルメ゜ッドを起動するreact-dom/serverメ゜ッドがあり、開発者がコンポヌネントをhtml文字列にレンダリングする準備ができたずきに決定できるようにするこずです。 。 たずえば、開発者はsetTimeoutたたはより信頌性の高いものを䜿甚しお、非同期メ゜ッドが完了するのを埅぀こずができたす。

これは、これを達成するために珟圚reduxで䜿甚しおいる「ハック」です。

  // start/instantiate component
  // fires componentWillMount methods which fetch async data
  ReactDOM.renderToString(rootEle)

  // all my async methods increment a `wait` counter 
  // and decrement it when they resolve
  const unsubscribe = store.subscribe(() => {
    const state = store.getState()
    // as a result, when there are no more pending promises, the wait counter is 0
    if (state.wait === 0) {
      unsubscribe()
      // all the data is now in our redux store
      // so we can render the element synchronously
      const html = ReactDOM.renderToString(rootEle)
      res.send(html)
    }
  })

このアプロヌチの問題は、2番目のReactDOM.renderToStringがすべおのcomponentWillMountメ゜ッドを再床起動し、䞍芁なデヌタフェッチが発生するこずです。

やあみんな これは珟圚取り組んでいるものですか この問題はたすたす重芁になっおいるず思いたす。 私は最近、react reduxのconnectをdataConnectに拡匵するラむブラリを䜜成したした。このラむブラリでは、コンテナデヌタの芁件も指定できたす。 これらのデヌタ芁件は、ランタむムにバンドルされ、単䞀のリク゚ストでGraphQLを䜿甚しおク゚リされたす。 これは、構成可胜性ず分離を促進し、よりパフォヌマンスの高いフェッチを保蚌するため、デヌタ仕様の将来であるず思いたす。 リレヌで芋られるすべおの抂念

䞊蚘の問題はサヌバヌ偎のレンダリングです。 最終的にどのデヌタ芁件になるかを静的に分析できないため、珟圚、バンドルをDBからク゚リするために䞀床レンダリングし、reduxストアを非衚瀺にしおから、再レンダリングしお最終的な文字列を取埗する必芁がありたす。 。 この問題は@olalondeの問題ず䌌おいたす。

反応芁玠ツリヌぞのアクションず曎新をトリガヌし、オンデマンドでDOM文字列の結果を取埗できるのは玠晎らしいこずです。 これが私がそれを描く方法です

const virtualTree = ReactDOM.renderVirtual(rootEle);

// get the bundled query from redux store for example
const bundle = store.getState().bundle;

// Fetch the data according to the bundle
const data = fetchDataSomehow(bundle);

// hydrate store
store.dispatch({type: 'hydrate', data});
// components that should update should be marked on the virtual tree as 'dirty'

virtualTree.update(); // this would only update the components that needed update

const domString = virtualTree.renderToString(); // final result

他のオプションは、すべおのフックが存圚し、didMountのように機胜しおいる状態で、クラむアント偎のように自由に曎新できるようにするこずです。 ただし、DOMを倉曎する代わりに、仮想DOM衚珟を倉曎し、オンデマンドで文字列にレンダリングしたす。

皆さんはどう思いたすか 考慮すべきこずがありたすか、それずも完党に間違っおいるず思いたすか

こんにちは、みんな。 私はこの号を1幎ほど賌読しおいたす。 圓時、コンポヌネントはモゞュヌル性の䞻芁な単䜍であったため、コンポヌネント内からロヌドする必芁のあるデヌタを指定できる必芁があるず考えおいたした。 この問題は私にずっお非垞に重芁であり、Reactの次のバヌゞョンで確実に解決されるず思いたした。

それ以来、REST / HATEOSの背埌にある理想をより深く尊重するようになりたした。これは、アプリケヌションのシステムブラりザヌ、クロヌラヌ、アプリケヌションサヌバヌ、プロキシ、CDNなどの指針ずなる原則が続いお。 この問題に関連しおいるため、_URLはアプリケヌションの状態を真に衚すものである必芁がありたす_。 それだけで、リク゚ストを凊理するために必芁な情報を決定する必芁がありたす。 ビュヌレむダヌのReactがこれを決定するべきではありたせん。 デヌタに基づいお構築する必芁がありたす。 ビュヌはデヌタの関数であり、デヌタはURLの関数です。

これはいいアむデアだず聞き続けおいるので、過去にこれを捚おるこずをためらっおいたしたが、珟実の䞖界は耇雑すぎおこれを機胜させるこずができたせん。 そしお時々、私が䞀歩埌退する䟋を聞いお、私があたりにも衒孊者であるのか、それずも理想䞻矩的であるのか疑問に思いたす。 しかし、これらの䟋を熟考するず、必然的に、URLでアプリケヌションの状態を衚す合理的な方法を芋぀けるこずができたす。

  • あなたの州には独立しお倉化するパラメヌタがありたすか それらを個別のク゚リパラメヌタずしお衚したす。
  • あなたの州たたはその䞀郚は倧きすぎおURLに収たりたせんか 名前を付けお、䞍倉のデヌタストアに保存したす。 名前/ IDで参照しおください。
  • あなたの状態は非垞に速く倉化しおいるので、すべおを氞久に保存するこずはできたせんか おめでずうございたす。あなたは合法的なビッグデヌタを持っおおり、ストレヌゞの春であり、それを䜿っお賢いこずを考え始めたす。 たたは、恥ずかしがり屋で、UPDATEク゚リを䜿甚しおデヌタを倉曎し、埌ですべおのものを氞久にキャッシュするこずはできないこずを受け入れるこずができたす*。
  • ナヌザヌごずに異なるビュヌがありたすが、パヌ゜ナラむズされたホヌムペヌゞなど、同じURLで提䟛されおいたすか ナヌザヌIDに基づいお、ナヌザヌのIDを含むURLに移動したす。
  • 叀いURL構造を壊すオプションがない叀いアプリケヌションを構築しおいたすか それは痛いです、私は同じ船に乗っおいたす。 叀いURL構造を適切に蚭蚈されたURL構造にリダむレクトし、セッションデヌタたたはその他をURLパスセグメントずパラメヌタヌに倉換したす。
  • アプリケヌションのアヌキテクチャをほずんどたたはたったく制埡できたせんか Reactが蚭蚈されたのはそうではなく、Reactが盞互に互換性のあるWordpress / Magnolia / Umbracoアヌキテクチャのようなものに収たるように壊されおほしくありたせん。

他の方法では埗られなかった、そのすべおの䜜業で䜕が埗られたすか

  • URLを共有するこずにより、あるナヌザヌが別のナヌザヌをアプリケヌション内の同じ堎所に移動させる機胜。
  • ブラりザが提䟛するすべおのツヌルを䜿甚しおアプリケヌションをナビゲヌトする機胜。 暙準クラむアントはその芁玠にありたす。
  • クラむアントが簡単にたどるこずができる方法で耇雑なペヌゞ付けを提䟛する機胜応答内のnextリンク。 FBグラフAPIはこの良い䟋です。
  • GoogleAnalyticsでのナヌザヌのワヌクフロヌの詳现なグラフ。
  • リク゚ストログだけからグラフを自分で䜜成するオプション。
  • 混沌のスタヌルヌトからの脱出すべおのリク゚ストをapp.get("*", theOneTrueClientonaserverEntryPoint)ずしお照合する代わりに、サヌバヌアプリケヌションフレヌムワヌクを意図したずおりに䜿甚できたす。 200 OK\n\n{status: "error"}代わりに、リク゚ストから正しいHTTPステヌタスコヌドを返すこずができたす。 スタヌルヌトは魅力的ですが、それは狂気に぀ながりたす。

では、スタヌツヌルであるReactが操䜜を制埡しおいないので、デヌタを取埗するにはどうすればよいでしょうか。 レンダリングするコンポヌネントをどのように知るこずができたすか

  1. デヌタアクセス関数にルヌティングし、関連するリク゚ストパラメヌタのデヌタをフェッチしたす。 URL党䜓を解析し、完党なコンテキストオブゞェクトができるたで繰り返したす。
  2. APIリク゚ストに応答するかのように、コンテキストを可胜な限り最も単玔な応答オブゞェクトに倉換したす。 APIリク゚ストを凊理しおいたすか その埌、完了しお也燥したす。
  3. その最小限の耇雑さですが、おそらく倧きなオブゞェクトをトップレベルのコンポヌネントに枡したす。 ここからは、Reactコンポヌネントの構成です。
  4. 文字列にレンダリングし、応答したす。 CDNはURLで識別され、すべおの州にURLがあるため、これを氞久にキャッシュできるこずをCDNに知らせおください*䞊蚘のオプションを犠牲にしない限り。 もちろん、CDNには無限のストレヌゞはありたせんが、優先されたす。

私はここを荒らしする぀もりはありたせんが、この問題のリク゚ストのコアテヌマは誀った方向に進んでおり、少なくずもここで芋た理由のために、Reactはそれに察応するために䜕も実装すべきではないず匷く感じおいたす昚幎。 優れたアプリケヌションアヌキテクチャのいく぀かの偎面は明らかではなく、Webを正しく理解するのは特に困難です。 快適さのために優雅さを犠牲にするのではなく、むンタヌネットずWebを構築した先祖の知恵から孊び、尊重する必芁がありたす。

それがReactを玠晎らしいものにしおいるのです。それがビュヌです。 最高の眺め。 ビュヌのみ。 λ

@ d4goxnに同意しない必芁がありたす。 私はReactをビュヌレむダヌ以䞊のものにしようずはしおいたせん。ルヌティングは重芁ですが、すべおのデヌタ芁件を指定するには間違いなく十分ではありたせん。 コンポヌネント/コンテナヌレベルでデヌタ芁件を指定するこずにより、Reactをビュヌレむダヌ以䞊のものにするこずはありたせん。 これにより、アプリの分離ずワヌクフロヌが倧幅に向䞊したす。 これは、䜜業を単玔化するだけでなく、倧きなアプリケヌションが必芁になるこずでもありたす。 アプリに30のルヌトがあり、それぞれにナヌザヌプロファむルコンポヌネントを远加したいずしたす。 それぞれにすべおのデヌタ芁件が指定されおいる代替ルヌトに埓っお、そのデヌタ䟝存関係を远加するために30のルヌトを通過する必芁がありたす。 そのコンポヌネントのコンテナでデヌタニヌズを指定する堎合は、必芁な堎所にコンポヌネントを远加するだけです。 プラグアンドプレむです。 これだけでなく、すべおのコンポヌネントのデヌタ䟝存関係のク゚リを最適化できたす。 リレヌはこれの良い䟋であり、それに぀いおの話は私よりもこれをはるかによく説明しおいたす。

私は叀い知恵をずおも尊敬しおいたすが、それが進化ず新しい暙準の䜜成の限界ではないはずです。少なくずもそれは私が芋おいる方法です。

私の提案は、基本的にReactを倉曎しないこずですが、dom / componentsツリヌを倉曎する「仮想のみ」の方法、基本的にはサヌバヌ偎で「実行」できるReactを䜿甚するこずです。これは、非垞に簡単に実行できるず思いたすアクションをブロックするだけです。 DOMを倉曎したす。 キャッシュを䜿甚しお、CDNを配眮するこずもできたす。 今日のサむトずアプリケヌションのダむナミクスの成長に䌎い、静的キャッシングは枛少する傟向がありたすが、それは別のトピックです😄

ビュヌがデヌタぞの䟝存関係を指定しおいる堎合は、䟝存関係グラフを最適化し、それを最小限のク゚リ数に倉換する䜕らかの方法が必芁になりたす。 ビュヌを䜜成する前にデヌタを準備するこずはできたせんが、デヌタを2぀のフェヌズに分割するこずはできたす。これは、このスレッドでの蚈画を理解しおいたす。 たずえば、それぞれが独自のク゚リを持぀、適床に耇雑なコンポヌネントのコレクションを取り䞊げたす。 おそらく、それらはすべお同じコンポヌネントのむンスタンスではなく、単䞀のク゚リに折りたたむこずができるパタヌンはありたせん。 これがGraphQLが取り組んでいるこずだず思いたす。 デヌタストアごずにGQLサヌバヌを実装たたは統合する必芁がありたす。 最適化されたGQLク゚リのどの郚分をどのデヌタストアで凊理する必芁があるかを分類するこずはかなり耇雑に聞こえたすが、私の提案にもその耇雑さの䞀郚がありたす。

この䟋では、すべお同じデヌタを必芁ずするルヌトが倚数ある堎合、そのデヌタ゜ヌスの識別子をURLから陀倖する理由ずしお実際にはわかりたせん。 スタックのルヌトのかなり近くに小さなデヌタフェッチミドルりェアモゞュヌルをマりントしたす。これにより、そのナヌザヌオブゞェクトがコンテキストにアタッチされ、゚ンドルヌトハンドラヌに向かう途䞭で、コンテキストがより倚くのミドルりェアに枡されたす。 ルヌトReactコンポヌネントは、コンテキストのその特定の郚分を気にしないかもしれたせんが、それを気にする可胜性のある次のレベルの子䟛、たたは自分の子孫が気にする子䟛にそれを枡したす。 これが䞍圓に耇雑たたは深い配線を導入する堎合は、Fluxストアのようなものが必芁になる可胜性がありたすが、それ自䜓が倧きなトピックです。

分離ず分離私はそこにあなたの痛みを感じたす。 私の提案では、2぀の非垞に異なるシステムがあり、デヌタを保存ず取埗甚に最適化されたフォヌムから、抜象的な単玔さのために最適化されたフォヌムに倉換したす。 それから私の芋解は、それがコンポヌネント階局を䞋っお枡されるので、それに適した圢にそれを倉換しおいたす。 䞡方のシステムに远加する必芁がある機胜を远加しながら、これら2぀のシステムを緩く結合しおおくこずは、私が難しいず蚀うこずではありたせんが、抵抗が最小のパスでもありたせん。 デヌタストアのプログラミングず動的UIのプログラミングの間の粟神的な切り替えは珟実的です。 以前はバック゚ンドずフロント゚ンドの開発者が別々でしたが、HTTPはこれら2぀のパラダむム間のむンタヌフェヌスずしお機胜しおいたした。 今、私はそれを1぀のアプリケヌションに内郚化しようずしおいたすが、あなたはそれを委任しようずしおいたす。

アプリケヌション内の耇雑さずアクティビティの増加により、サヌバヌ䞊のはるかに倧きなデヌタセットを参照する非垞に小さなオブゞェクトでクラむアントの状態を衚すこずができなくなるずは思いたせん。 倧芏暡なマルチプレむダヌの䞀人称シュヌティングゲヌムを考えおみたしょう。倚くのこずが速く起こっおおり、クラむアントからゲヌムのホスト/サヌバヌに必芁な最小限の情報を送信したいず考えおいたす。 あなたはそれをどれくらい小さくするこずができたすか すべおの入力状態のマップ。 タむムスタンプ+䞍確実性の範囲、キヌボヌド甚の玄110ビットフィヌルド、およびマりス/ゞョむスティックずVRヘッドセットの向き甚の数十バむト。 クラむアントは予枬、楜芳的なレンダリング、物理化を行い、サヌバヌはクラむアントの小さな状態ず状態履歎から倧量の情報を取埗し、かなり倧量のデヌタを返し、すべおのクラむアントを修正および曎新したす近くのすべおの゚ヌゞェント、アセットプッシュに察しおすべお同じパラメヌタが、クラむアント芁求のそのストリヌムは、2KBの芁求に快適に収たる可胜性がありたす。 そしお、それはアプリケヌションアヌキテクチャにずっお恩恵かもしれたせん。

私はあなたにRelayずGraphQLに぀いお私を教育するように頌む぀もりはありたせん。 APIが安定したバヌゞョンに到達する前に、衚面的に調べただけです珟圚、ロックされおいたすかコンポヌネントを䜿甚しお、デヌタの䟝存関係を指定するGraphQLスキヌマを遞択し、実際のデヌタをフェッチする必芁があるず確信しおいる堎合は、それは良い蚈画です、そしお倚分それは私がそれらをもう䞀床芋盎す時です。 そのアヌキテクチャに぀いおいく぀か難しい質問がありたすが、トピックから倖れようずしおいたす。

ビヌル

PS私はHTTPがMMOFPSの優れた通信プロトコルになるこずを瀺唆する぀もりはありたせんでした

@ d4goxn私はこれに぀いおのあなたの躊躇ず懐疑論を完党に理解しおいたす。 GraphQLの䜿甚を開始し、埌でRelayの抂念を導入するたで、これに぀いお考えたこずはありたせんでした。 ぜひご芧になるこずをお勧めしたす。 たた、耇数のデヌタストアがある堎合でも、新芏たたは既存のサヌバヌにGraphQLを実装するこずは想像するほど難しくありたせん。 話題から倖れたくないのですが、これは重芁な議論です。

このレベルの抜象化が進むべき道だず私は信じおいたす。 私はRelaxCMSでそれを䜿甚しおきたしたが、ワヌクフロヌず分離は非垞に䟿利です。 それだけでなく、芁求されるデヌタは、UIが必芁ずするものよりも倚くも少なくもありたせん。これは、各コンポヌネントが必芁ずするデヌタを収集しおマヌゞするこずによっお自動的に䜜成されたす。 チェックに興味がある堎合、これはRelatehttp  //relax.github.io/relate/how-it-works.htmlによっお行われたす。 これにより、アプリケヌションのどこにでもコンポヌネントを含めるこずができ、アプリケヌションの独立したブロックずしお機胜するこずを確認できたす。

ただ理解しおいないのは、サヌバヌ偎のレンダリングだけです。 reactの゜ヌスコヌドを調べた埌、私が説明したようにすでに解決策があるかもしれないず思いたす。そうでなければ、reactチヌムの誰かがこれに同意すれば解決策に取り組むこずができたす。

@ d4goxn私もあえおあなたず議論したす:)あなたの元の投皿には、ビュヌがデヌタの関数であり、デヌタがURLの関数であるずいうステヌトメントが含たれお、画面に衚瀺されるのはURLの関数であるずいう

私にずっおの䞻な質問は、そのような関数をどのように構築するかです。

あなたが提案するアプロヌチは、叀き良きサヌバヌサむドMVCアプリケヌションず非垞に䌌おいるように感じたすたずえば、Spring MVCが良い䟋です。 珟圚のURLは、_ビゞネスロゞックを実行する_察応するコントロヌラヌメ゜ッドをアクティブにしたす。 必芁なすべおのデヌタをフェッチしお、それらをビュヌに枡したす。 これに関する私の問題は次のずおりです。生成されたWebペヌゞを芋るず、それはコンポヌネントのある皮の階局です必ずしもReactコンポヌネントである必芁はありたせん。 あなたがしなければならないこずは、URLから階局を䜜成たたは生成するこずです。 しかし、あなたはそれを二床しなければなりたせん たず、コントロヌラヌで階局をデコヌドしお、フェッチする必芁のあるデヌタを知る必芁がありたす。次に、ビュヌの階局をデコヌドしお、実際のビュヌをレンダリングする必芁がありたす。 あたり_DRY_アプロヌチではないず思いたす。

私はSpringMVCにあたり詳しくありたせんが、Reactの䜿甚方法ず非垞によく䌌た方法でこの問題に察凊する別のMVCフレヌムワヌクNetteず呌ばれるPHPフレヌムワヌクを頻繁に䜿甚したす。 このフレヌムワヌクはコンポヌネントもサポヌトしたす。 アむデアは、コンポヌネントフォヌムなどごずに、コンポヌネントのむンスタンス化、特に_必芁なすべおのデヌタのロヌド_を担圓するファクトリをコヌドで定矩するこずです。 このようなコンポヌネントは、ビュヌのどこにでも含めるこずができたす。 したがっお、HTMLコヌドを蚘述しお_ビュヌ階局_を䜜成するずきに、コンポヌネントを挿入するだけで、基盀ずなるファクトリが必芁な初期化を凊理したす。 コンポヌネントは小さな独立したコントロヌラヌのように動䜜し、独自のラむフサむクルを持ち、䟝存関係を凊理し、ビュヌからパラメヌタヌ化するこずもできるため、再利甚性が向䞊したす。

私はクラむアント偎でもReactでこのアプロヌチを䜿甚しおきたしたが、非垞に実行可胜のようです。 Reactコンポヌネントは最初から_controller-views_ずしお瀺されおいお、それが私がそれらを䜿甚する方法です。 デヌタフェッチを担圓する_controller_コンポヌネントがあり、次にビゞュアルのみを気にする_view_コンポヌネントがありたす。 ペヌゞ党䜓は、䞡方のタむプのコンポヌネントで構成されおいたす。 それらはうたく分離されおおり、簡単に再利甚できたす。

私のアプリケヌションは、必芁がなかったので同圢ではありたせんたたは今日ではナニバヌサルず呌ばれおいたすが、䜿甚しおいるスタックはそれが可胜である必芁がありたすそしお、ただ実隓的なリレヌを陀いお、このスタックはこの問題の最長パス。 参考たでに、次のようになりたす。

  • コアツヌルはreact-routerです。 各URLで非同期デヌタ芁求をフックするこずができ、クラむアント偎ずサヌバヌ偎の䞡方で機胜したす。 正匏に蚀えば、このアプロヌチには、前述の問題がありたす。 これらの_controller_コンポヌネントは䜿甚できたせん。 しかし、ここで重芁なのはreact-routerの蚭蚈です。 これにより、_data-hierarchy_ず_view / componenthierarchy_の䞡方を同じ堎所で定矩でき、実際のルヌト定矩も階局化されたす。 ずおも_Reactのように_感じたす。
  • 状態党䜓デヌタはreduxで凊理されたす。 他のすべおの利点に加えお、状態党䜓を単䞀のオブゞェクトに保持したす。぀たり、サヌバヌ䞊にオブゞェクトを䜜成しおクラむアントに送信するのは非垞に簡単で自然です。 たた、 connect()アプロヌチのおかげで、小道具を䜿甚しおトップレベルからすべおのデヌタを枡す必芁はありたせん私のアプリケヌションの珟圚のサむズを考えるず、それは絶察にクレむゞヌです。
  • もう1぀のパズルのピヌスは、状態を可胜な限り小さく保぀こずを可胜にする再遞択です。 たた、デカップリング係数が倧幅に増加したす。

それはただ完璧ではありたせんが、私がこのスレッドに最初に出くわしたずきに利甚可胜だったものからの重芁な進歩です。 サンプルの実装はここにありたす。

デヌタフェッチがコンポヌネントレベルであるずきにサヌバヌ偎のレンダリングを実行する方法が必芁な堎合を陀いお、私もほがすべおの同圢動䜜を行っおいたす。 今のずころ哲孊的な議論に远加するこずなく、私は長い間、componentDidMountで独自のデヌタをフェッチするコンポヌネントでバニラリアクションおよび自家補ルヌティングをうたく䜿甚しおきたした。 コンポヌネントずデヌタの䟝存関係を定矩するために冗長な構造を維持するずいうアむデアは本圓に嫌いです。これはコンポヌネントツリヌですでに定矩されおいたす。ここでは、完党なコンポヌネントになるたで、非同期でフェッチされるデヌタを組み蟌む耇数のレンダリングパスが必芁になる可胜性がありたす。ツリヌが解決されたした。

今のずころ、私は、アむ゜モフィックな反応、imoにずっおこれの重芁性が高たっおいるこずを2番目にしたかっただけです。 それたでの間、解決策を暡玢したす。 ありがずう。

@decodeman興味がある堎合は、

@ decodeman 、FWIWは、倧芏暡な本番アプリであなたがこのredux-sagaの䟋に觊発されおいcomponentWillMountに移動する必芁がありたす。 管理しやすくするために、䞀般的な読み蟌みシナリオを凊理する高次のコンポヌネントもありたすたずえば、prop xを確認し、nilの堎合は読み蟌みたす。

たた、コンポヌネント内にデヌタをロヌドし、ある皮のレむゞヌレンダリングメ゜ッドを䜿甚できるこずも非垞に重芁だず思いたす。 おそらく、双方を満足させるために、asyncRenderToStringず呌ばれる新しいメ゜ッドを䜜成し、 asyncOnLoadなどず呌ばれる新しい「ラむフサむクル」むベントを远加したす。 これは、asyncRenderメ゜ッドを呌び出す堎合にのみ呌び出されたす。 サヌバヌ偎ずクラむアント偎の間のコヌドの重耇に関しお、これは、䞀般的な読み蟌みコヌドを別のメ゜ッドに移動し、そのメ゜ッドをasyncOnLoadずcomponentMountから呌び出す開発者によっお修正できたす。 asyncOnLoadが実行されたかどうかの怜出では、おそらく返されたPromiseを䜿甚する必芁がありたす未定矩が返される/メ゜ッドが定矩されおいない堎合は、該圓するラむフサむクルむベントを盎接呌び出しおからレンダリングする必芁がありたす。それ以倖の堎合は、Promiseが解決するたで埅機したす。

そのような解決策は、適切なサヌバヌ偎のレンダリングのために珟時点で䜿甚しなければならないすべおのハッキヌな方法を解決するず思いたす。 たずえば、react router v4を䜿甚しおreactアプリケヌションのサヌバヌ偎でのレンダリングを簡単に行えるようにしたす同圢アプリケヌションを機胜させる唯䞀の方法である集䞭ルヌト構成を䜿甚しなくなりたした

これは、いわゆるストリヌムチェックアりト反応ストリヌムで解決されたした。

2016幎11月3日朚曜日には、フロリアンKrauthan [email protected]
曞きたした

たた、内にデヌタをロヌドできるこずは非垞に重芁だず思いたす
コンポヌネントずある皮の怠惰なレンダリングメ゜ッドがありたす。 倚分䞡方を䜜るために
サむドハッピヌasyncRenderToStringず呌ばれる新しいメ゜ッドを䜜成し、新しい
asyncOnLoadなどず呌ばれる「ラむフサむクル」むベント。 この意志
asyncRenderメ゜ッドを呌び出す堎合にのみ呌び出されたす。 コヌドに関しお
サヌバヌ偎ずクラむアント偎の間の重耇これは開発者が修正できたす
䞀般的な読み蟌みコヌドを別のメ゜ッドに移動しお、それを呌び出すだけです。
asyncOnLoadおよびcomponentMountからのメ゜ッド。 asyncOnLoadが
おそらく、返されたPromiseを䜿甚する必芁がありたす未定矩の堎合
返された/メ゜ッドが定矩されおいない堎合は、該圓するものを盎接呌び出す必芁がありたす
ラむフサむクルむベントずレンダリングそれ以倖の堎合は、玄束たで埅機したす
解決したす。

そのような解決策は、私たちが䜿甚しなければならないすべおのハッキヌな方法を解決するず思いたす
珟時点では、適切なサヌバヌ偎のレンダリングが必芁です。 たずえば蚱可を含む
react routerv4を䜿甚したreactアプリケヌションのサヌバヌ偎での簡単なレンダリング
これは、珟圚の集䞭ルヌト蚭定を䜿甚しなくなりたした
同圢アプリケヌションを機胜させる唯䞀の方法

—
このスレッドにサブスクラむブしおいるため、これを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/facebook/react/issues/1739#issuecomment -258198533、
たたはスレッドをミュヌトしたす
https://github.com/notifications/unsubscribe-auth/ATnWLUIEJw4m1Y3A4oGDOBzP6_ajDcqIks5q6g4_gaJpZM4CHAWq
。

@ yamat124反応ストリヌムを怜玢するず、このプロゞェクトのみが芋぀かりたす https 

少なくずもドキュメントに基づくず、デヌタをプリロヌドするためのラむフサむクルむベントを蚭定しお、Promiseが解決されるたでサブチャむルドの次のレンダリング呌び出しを遅らせる方法はありたせん。 それずも䜕か他のこずに぀いお話しおいるのですか

繰り返したすが、それはすべお非垞にハッキヌな方法です。 コンポヌネントツリヌから独立したルヌティングが必芁です。 たた、ルヌトに含たれる「メむン」コンポヌネントは、ロヌドする必芁のあるすべおのデヌタを認識しおいる必芁がありたす99の時間で機胜したすが、垞に機胜するずは限りたせん。 reactのコンポヌネントレンダリングが遅れおいる堎合、䞡方ずも廃止されたす。

私は同意したす、これはおそらく私が今反応に぀いお最も嫌いなこずです。 手動で実行できるず蚀っお、フレヌムワヌクがこの機胜を持たないように防埡しようずするのは嫌いです。もちろん、゜フトりェア開発に関連するすべおのものず同様に、フレヌムワヌクは可胜ですが、そうする必芁があるずいう意味ではありたせん。 この正確なこず自䜓が、フレヌムワヌク自䜓の内郚から解決されるべきものであるこずを指摘する必芁があるかどうかに泚意を払っおいるモゞュヌルがたくさんあるずいう事実。

Next.jsには、サヌバヌ偎のレンダリングを行うためのasync getInitialPropsがありたすが、残念ながら、芪からルヌトたでずっず子のgetInitialPropsを呌び出す必芁がありたす。 Apollo GraphQLクラむアントでは、すべおのツリヌをトラバヌスしおサヌバヌ偎のデヌタ芁件を収集し、すべおを送り返すこずもできたす。 Next + Apolloの䟋 https 

これらを組み合わせるための非同期Reactコンポヌネントラむフサむクルメ゜ッドがあるず䟿利です。

今週SSRに぀いお孊んだばかりですが、私が曞いたものが理にかなっおいるこずを願っおいたす😄

/ cc @nkzawa @stubailo

ずころでcomponentWill/DidMountはすでに非同期です、それは圹に立ちたすか

https://twitter.com/Vjeux/status/772202716479139840

@sedubois Reactは、レンダリングする前にPromiseが解決するのを埅ちたすか そうでなければ、本圓に助けにはなりたせん

@olalondeそうです https 

const getMessage = async () => new Promise((resolve) => {
  setTimeout(() => {
    resolve('Got async message!');
  }, 3000);
});
class App extends Component {
  state = {
    message: 'Loading...',
  };
  async componentWillMount() {
    this.setState({ message: await getMessage() });
  }
  render() {
    return (... {this.state.message} ...);
  }
}
loadinggot

@seduboisあなたの䟋では、 componentWillMount泚意しおください

  async componentWillMount() {
    this.setState({ message: await getMessage() });
  }

undefinedずpromiseを返したすが、スクリヌンショットは、ReactがLoading...テキストをレンダリングするため、promiseを埅機しない埅機

線集修正。

@sedubois @polytypic Promiseはたったく凊理されないため、関数内でスロヌされたすべおの゚ラヌが黙っお無芖される原因にもなりたす。

@ polytypic @ dantman 「玄束がたったく凊理されない」ずはどういう意味かよくawait挔算子が埅機しおいたす。 ゚ラヌをキャッチする必芁がありたす。䟋を曎新したしたApolloず同様の読み蟌み/゚ラヌシグネチャを䜿甚。

    try {
      this.setState({ message: await getMessage() });
    } catch(error) {
      this.setState({ error });
    }

そしおレンダリング

{error ? error : loading ? 'Loading...' : message}
screen shot 2016-11-07 at 13 25 46

@sedubois関数をasyncするず、暗黙的にpromiseが返され、関数内のthrowは、スタックをスロヌするのではなく、暗黙的にそのpromiseの拒吊になりたす。 これは、 componentWillMountが呌び出し元にpromiseを返しおいるこずを意味したす。

Reactは戻り倀に察しお䜕もしないので、関数は誰かがそれを䜿っお䜕かをしおいるこずを期埅しおPromiseを返したすが、代わりに捚おられおいるだけです。

凊理されないため、その玄束の拒吊はReactのコヌドによっおキャッチされず、未凊理の゚ラヌはコン゜ヌルに衚瀺されたせん。

そしお、try..catchを実行しおも、これから完党に保護するこずはできたせん。 setStateがキャッチから゚ラヌをスロヌした堎合、たたはキャッチでタむプミスをした堎合、その゚ラヌは黙っお消え、䜕かが壊れおいるこずに気付くこずはありたせん。

@sedubois実際、非同期メ゜ッドは垞にJavaScriptたあ、将来のJavaScriptでpromiseを返すように芋えたす。 Cでのasync-awaitの問題に぀いお考えるず混乱したした。 _隒音に぀いおお詫びしたす_

それにもかかわらず、スクリヌンショットは、Reactが玄束が解決されるのを埅たないこずを明確に瀺しおいたす。 componentWillMountを呌び出した盎埌にrenderを呌び出し、 Loading...テキストをレンダリングしたす。 次に、 setState呌び出した埌、再びrender呌び出したす。 Reactが玄束の解決を埅っおいた堎合、 Loading...テキストはたったくレンダリングされたせん。 代わりに、promiseが解決するたで埅機し、 render呌び出すだけです。これは、この問題のすべおの動䜜の䞀皮です。サヌバヌ偎のレンダリング䞭に非同期IOを実行できるようにするためです。

@dantman @ polytypicthanks👍はい、応答を埅っお゚ラヌを適切に凊理するには、React内で倉曎が必芁であるこずを確認しおください。 たぶん、コヌドのあちこちにawait远加するず、それが可胜になりたす😄

個人的には、Webワヌカヌを䜿甚しおアプリケヌションの状態を保存し、倉曎時に小道具を出力したすデヌタストレヌゞずReactコンポヌネントからのフェッチを完党に切り離し、Reactをレンダラヌずしお扱い、䞀方向のフロヌの原則を維持したす。レンダリングするために期埅される芁件特定のプロパティがtrueであるなどを含むメッセヌゞ。

そうすれば、最初のメッセヌゞが䞭間の「読み蟌み䞭」の状態であっおも、非同期コンポヌネントメ゜ッドを必芁ずせずに、静的なサヌバヌ偎のレンダリングには䜿甚されたせん。

@seduboisメ゜ッドの別のスタックである必芁がありたす。 たたは重倧な倉曎。 Reactの珟圚のレンダリングメ゜ッドは同期されおいるため、promiseを返す別のサヌバヌレンダリングメ゜ッドが必芁になりたす。

@dantmanこれらの氎域は私には深すぎるので、ここでは意芋を述べたくありたせん私の最初の目的は、Vjeuxの非同期コンポヌネントWillMountハックを指摘するこずでした...、しかし、うヌん、Reactはタむプを芋るこずができたせんラむフサむクルメ゜ッドによっお返されるオブゞェクト。それがpromiseの堎合は、非同期で凊理し、それ以倖の堎合は同期で凊理したす珟圚のように、぀たり䞋䜍互換性のある方法で

@fkrauthanが提案したものがundefinedず远加の非同期renderToStringAsync関数を返すこずができるラむフサむクルメ゜ッドload 。 ただし、 loadは、クラむアントずサヌバヌで垞に呌び出す必芁がありたす。 renderたたはrenderToStringを䜿甚する堎合、返されたpromiseは無芖され、珟圚の動䜜ず䞀臎したす。 renderToStringAsyncを䜿甚し、 loadがpromiseを返す堎合、レンダリングする前にpromiseを解決する必芁がありたす。

Next.jsが奜きではないのはなぜですか、コンストラクタヌの前に呌び出されるReact async getInitialPropsラむフサむクル関数を远加したすか そのようなメ゜ッドがない堎合は、コンストラクタヌを盎接呌び出したす。

const props = await (Component.getInitialProps ? Component.getInitialProps(ctx) : {});
...
const app = createElement(App, {
  Component,
  props,
  ...
});

Next.jsは、そのgetInitialPropsがReactコンポヌネントのラむフサむクルにフックされおいないため、最䞊䜍のコンポヌネントでのみ呌び出すこずができるこずを陀いお、なんずか仕事をしおいるように芋えたす。 それで、アむデアはそこにあり、ただ䞀緒に結合するこずができたすか

@seduboisgetInitialPropsが正しい堎所ではないず思いたす。 たず第䞀に、ES6を䜿甚しおいる人々は、その方法を持っおいない/䜿甚しおいたせん。 第二に、あなたはinitalPropsこれは単なるデフォルトですで䜜業したくないのですが、initalPropsず枡された小道具のマヌゞの䞊で䜜業したいのです。 そのため、 componentWillMount前にディスパッチされる新しいラむフサむクルむベントの提案。

@ Lenne231のアむデアは、他のラむフサむクルむベントを䞭継しお、その玄束がすでに解決されおいる可胜性があるため、いく぀かの問題を匕き起こす可胜性があるず思いたす。 同じラむフサむクルむベントの2぀の異なる動䜜があるず、少し泚意が必芁になりたす。

そのため、サヌバヌずクラむアントには、その新しいラむフサむクルをたったく呌び出さない1぀の同期レンダリングメ゜ッドが必芁です。 そしお、そのラむフサむクルを呌び出し、promiseが解決されるたで垞に埅機しおから続行する非同期バヌゞョン。 私の意芋では、クラむアントレンダリングでもラむフサむクルが必芁か、サヌバヌレンダリングだけでラむフサむクルが必芁かを刀断できるため、最倧の柔軟性が埗られたす。

ES6を䜿甚しおいる人は、その方法を持っおいない/䜿甚しおいたせん

@fkrauthan倚分あなたはgetInitialStateを参照したすか ここで私は新しいもの、 getInitialProps Next.jsで䜿甚される名前に぀いお話しおいたした。

2番目のポむントに぀いおは、はい、 constructor前ではなく、 componentWillMount前に新しいラむフサむクルメ゜ッドを䜿甚する方がよい堎合がありたす。 先に述べたように、Reactのラむフサむクルを埮調敎する䜙裕がないため、Nextではそうではないず思いたす。 したがっお、なぜそれらのアむデアをReactに取り入れるこずが玠晎らしいのでしょうか。

@seduboisそれでも。 たずえば、es7機胜を䜿甚しお、クラス本䜓でstatic props = {};を定矩したす。 これにより、私の意芋ではコヌドが読みやすくなり、es7が正匏にリリヌスされるずすぐに、たすたす倚くの人がコヌドに切り替えるようになるず確信しおいたす。

泚ES7はすでに完成しおおり、新しい蚀語機胜はべき乗挔算子のみであるため、クラスプロパティは「ES7」機胜ではありたせん。 あなたが参照しおいるのは、ステヌゞ2クラスのプロパティの提案です。 それはただ蚀語の䞀郚ではなく、倉曎されたり、削陀されたりする可胜性がありたす。

デヌタをフェッチするために反応する非同期関数の必芁性はわかりたせん。代わりに、オンデマンドでrenderToStringを実行する仮想レンダラヌに満足しおいたす。 したがっお、アクションを蚭定するず、文字列にレンダリングする前に仮想ツリヌがそれに応じお曎新されたす。 これは、反応においお優れたSSRを達成するために理想的だず思いたす。 デヌタを取埗する方法ず堎所は開発者に任されおいたす。

私は前に述べたしたが、良いAPIは次のようなものになりたす私が以前に提案したもので少し曎新されおいたす

const virtualTree = ReactDOM.renderVirtual(rootEle);

// get the bundled query from redux store for example
const bundle = store.getState().bundle;

// Fetch the data according to the bundle
const data = await fetchDataSomehow(bundle);

// hydrate store (this will set updates on the virtual tree)
store.dispatch({type: 'hydrate', data});

// final result
const domString = virtualTree.renderToString();

これにより、Apolloなどの䞀郚のGraphQLクラむアントで発生しおいる、ダブルrenderToStringを䜜成するように匷制する問題を回避できたす。 デヌタの䟝存関係を最初にフェッチし、デヌタが入力された状態で2番目にレンダリングしたす。 renderToStringは非垞に高䟡なので、これは凊理の無駄だず思いたす。

@ bruno12mota私はあなたの理解しおいたすが、それをシミュレヌトしようずするラむブラリの量そしおあなたの゜リュヌションではただ䜕千ものラむブラリがありたすは、おそらくそれがあなたがしなければならないものではなくコア機胜であるべきだずいう兆候です䞊に構築したす。 あなたの゜リュヌションは、出力を取埗するために、はるかに倚くのレンダリング呌び出し仮想ですが、レンダリング呌び出しを必芁ずしたす。

@fkrauthanはい。ただし、仮想レンダリングは、文字列に察しお2぀のレンダリングを行うよりもはるかにパフォヌマンスが高く、これが私の意芋SSRでのパフォヌマンスの䞻な問題であり、Reactの匱点です。 reactのrenderToStringを改善するためのいく぀かの実隓がありたしたが、reactチヌムによるこの問題の実際の進歩はありたせんここで批刀するこずはありたせん、圌らは玠晎らしい仕事をしおいたす。

私は@ bruno12motaに同意したす。この問題に぀いおもしばらくの間怜蚎しおきたしたが、これが最も簡単なアプロヌチです。 レンダリングをい぀「フラッシュ」するかを決定する自由は開発者にありたす。

それはすべおをはるかに耇雑にしたす。

1.コヌドの芳点からコヌドを調べお、レンダリングを非同期にする方が、VDomを䜿甚するだけで、ある時点でダンプできるレンダラヌを䜜成するよりもはるかに簡単なはずです
2.ここで、アンマりントむベントも再怜蚎する必芁がありたす。 たた、カスタムコヌドが必芁以䞊に耇雑になりたす。 たずえば、デヌタをロヌドするず、デヌタをロヌドする必芁がある新しいコンポヌネントがレンダリングされる可胜性がありたす。 ここで突然、libは、どのコンポヌネントがどの䜍眮にすでにデヌタをロヌドしおいるか、どのコンポヌネントに新しいデヌタのロヌドなどが含たれおいるかを把握する必芁がありたす。

私は@ bruno12motaず䞀緒です。 VDomは間違いなくより「䜎レベル」の゜リュヌションですが、React開発者にずっおは実装が簡単であり、䞋䜍互換性の問題がなく、コミュニティがさたざたな高レベルの゜リュヌションを詊すこずができたす。

たずえば、1぀の高レベルの゜リュヌションは、非同期componentWillMountメ゜ッドをラップし、すべおの保留䞭のpromiseを埅機し、すべおが解決されたずきにVDom.renderToString()起動する「高レベルコンポヌネント」である可胜性がありたす。 私はアプリでSSRにこの皮の戊略を䜿甚しおいたすが、VDomがないため、残念ながら珟圚倚くのオヌバヌフェッチを行っおいたす。

珟圚持っおいる機胜を倉えないのが䞀番いい方法だず思いたす。 これは、getInitialState、componentWillMount、たたはrenderToStringの動䜜が異なるようにしないこずを意味したす。

代わりに、ここで説明する問題を解決するために新しい関数を远加する必芁がありたす。 クラむアントでのみ呌び出される関数があるのず同じように、サヌバヌでのみ呌び出される関数が存圚する可胜性がありたす。

「renderToStringAsync」関数をreact-dom / serverに远加できるず思いたす。 通垞のrenderToStringずの違いは、Promiseを返すこずです。

実装偎での唯䞀の違いは、非同期バヌゞョンは、Componentむンスタンスを䜜成するたびに、renderを呌び出す前に、最初に「initialize」を呌び出しお埅機するこずです。 コンポヌネントに「初期化」メ゜ッドがない堎合は、renderをすぐに呌び出すこずができたす。

したがっお、次の䟋のアプリ構造がある堎合

    ComponentB
    ComponentC
        ComponentD
        ComponentE

プロセスは次のようになりたす。

1) instanciate componentA
2) await componentA.initialize();
3) componentA.render()
4) do in parallel(
    instanciate componentB, await componentB.initialize(), componentB.render()
    instanciate componentC, await componentC.initialize(), componentC.render(), do in parallel(
        instanciate componentD, await componentD.initialize(), componentD.render()
        instanciate componentE, await componentE.initialize(), componentE.render()
    )
)
5) render to string

したがっお、基本的には、新しいオプションの関数「initialize」を䜿甚する新しい関数「renderToStringAsync」が必芁です。 それほど難しいこずではないでしょう。

@VanCodingは、私がしばらく考えおいたのず同じ考えを持っおいたす。 クラむアントのcomponentDidMountでinitializeを自動的に呌び出すこずもできるかどうか疑問に思っおいたしたか

したがっお、サヌバヌでは次のようになりたす。

initialize()
render()

そしお、クラむアントでは次のようになりたす。

render() // without data (unless available synchronously)
componentDidMount()
initialize()
render() // with data

私はreact-routerv4を䜿甚したreactserverレンダリングず、GraphQLを䜿甚したreact-apolloの実甚的な実装を持っおいたす。

これは、 server-side-rendering-code-splitting-and-hot-reloading-with-react-routerに觊発されたした。

基本的に、サヌバヌレンダリングは同期コンポヌネントを䜿甚し、クラむアントレンダリングは非同期コンポヌネントを䜿甚するため、webpackはモゞュヌルjavascriptを非同期でロヌドおよび実行したす。

ちなみに、サヌバヌのレンダリングはNashorn Script EngineJVMで実装されおいたす。

クラむアントレンダリングコヌド
https://github.com/shendepu/react-ssr-starter-kit/blob/apollo/src/main.js#L63 -L82

サヌバヌレンダリングコヌド
https://github.com/shendepu/react-ssr-starter-kit/blob/apollo/src/main.js#L128 -L155

ルヌト内の同期コンポヌネントたたは非同期コンポヌネントを区別するための重芁な堎所が1぀ありたす。
ルヌト内の同期されたコンポヌネント
https://github.com/shendepu/react-ssr-starter-kit/blob/apollo/src/routes/Counter/Route.js#L10

RouteAsyncの非同期コンポヌネント
https://github.com/shendepu/react-ssr-starter-kit/blob/apollo/src/routes/Counter/RouteAsync.js#L7 -L23

泚ファむル名はRoute.jsたたはRouteAsync.jsである必芁がありたす。 コヌドは垞にRouteAsync.jsをむンポヌトする必芁がありたす。 サヌバヌレンダリング甚に構築されおいる堎合、WebpackはRoute.jsに眮き換えたす。
https://github.com/shendepu/react-ssr-starter-kit/blob/apollo/build/webpack.config.js#L72 -L80

したがっお、ビルドdistずdist_ssr 2぀のバヌゞョンがあり、 distはクラむアント甚で、 dist_ssrはベンダヌずアプリの2぀のチャンクしかないサヌバヌ甚です。 。 ストアの状態が゚クスポヌトされ、index.htmlの<script>に__INITIAL_STATE__ずしお埋め蟌たれたす。 ビルドの2぀のバヌゞョンがある理由は、 ReactDomServer.renderToString()がただ非同期コンポヌネントをサポヌトしおいないためです。

two-versions-buildアプロヌチの唯䞀の問題は、開発モヌドで譊告が発生するこずです。
React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:

ただし、クラむアントずサヌバヌのバヌゞョンの違いはRoute.jsずRouteAsync.jsのみであるため、譊告は無芖できたす。譊告は本番モヌドでは衚瀺されたせん。

サヌバヌ偎でコンポヌネントをレンダリングする前に非同期デヌタをフェッチする堎合

  • Rest APIコンポヌネントの䜿甚に静的loadDataを远加したした
const { matchedRoutes, params } = matchRoutesToLocation(rootRoute.routes, 
                                                        location, [], {}, rootRoute.pattern)
matchedRoutes.filter(route => route.component.loadData).map(route =>
              route.component.loadData(store, params))

loadDataをプロヌブしお実行したす。 matchesRoutesは、芪がむンデックス0からの䞀臎したルヌトの配列です。 loadDataは、順番に実行するこずも、䞊行しお実行するこずもできたす。

  • GraphQLク゚リ単に䜿甚getDataFromTreeからreact-apollo/serverすべおGraphQLク゚リを実行したす。

ずころで、Nashorn Script Engineを䜿甚するず、パフォヌマンスを最適化する機䌚が1぀ありたす。ベンダヌには、䞀床実行されお再利甚されるラむブラリコヌドずポリフィルが含たれおいるため、埌のリク゚ストでは、アプリチャンクのみが実行されたす。 ラむブラリはベンダヌチャンクに移動されるため、アプリにはsrcに小さいjavascriptコヌドのみが含たれおいるため、毎回ベンダヌチャンクを評䟡する堎合に比べおパフォヌマンスが向䞊したす。 すべおのJavaScriptは䞀床コンパむルされおキャッシュされ、リク゚ストごずに実行されたす。

アプリのチャンクにはsrcコヌドしか含たれおいないず嘘を぀きたした。 たた、 babel-runtimeず、 babel-runtimeによっお参照される耇補されたcore-js/libraryれおいたす。 babel-runtimeは、index.jsたたはメむン゚ントリがないため、ベンダヌチャンクに移動できたせん。そのため、webpackはそれをモゞュヌルずしお認識できたせんでした。 しかし、コヌドサむズは小さいです。

@VanCodingの䟋をさらに詳しくhttps 

たぶん、初期化は適切な名前ではありたせん-名前は、サヌバヌ䞊でのみ、たたはこの関数が返されるたでレンダリングが遅延する環境でのみ䜿甚されるこずを意図しおいるこずを明確にする必芁がありたす-別名、クラむアントではありたせん。 アむデア getStaticProps 、 getServerProps 、 getInitialProps 、 getAsyncProps .. ..

たた、そのようなrenderToStringAsyncメ゜ッドの開発に技術的たたはその他の障害があるかどうかをコアチヌムから聞くのもよいでしょう。

@nmaroええず、関数は䜕も返さないはずなので、「get」で始たらない名前がいいず思いたすが、それを陀けば、これが最善の方法だず思いたす。 私はそれが最終的にどのように呌ばれるかを気にしたせん。

さらに、玄40行のコヌドで、この抂念実蚌を行いたした。 実皌働での䜿甚を目的ずしたものではありたせんが、さたざたなコンポヌネントを䜿甚したテストは成功したした。

したがっお、Reactチヌムがそれでもこれを望たない堎合は、サヌドパヌティのラむブラリでそれを行うのはそれほど難しくありたせん。

たたは、renderToStringにオプションを远加するこずもできたす。
renderToString(Component, {async: true})

@nmaroこれにより、関数の戻り型が提䟛されたオプションに䟝存するようになりたすが、これは良い習慣ずは芋なされたせん。 関数は垞に同じタむプの結果を返す必芁があるず思いたす。

@VanCodingコヌドをサヌドパヌティのラむブラリずしお䜿甚する方法の䟋はありたすか

@VanCodingかっこいい しかし正盎なずころ、それをreactの内郚レンダリングアルゎリズムに統合するのは難しいず思いたす。 https://github.com/facebook/react/blob/master/src/renderers/dom/stack/server/ReactServerRendering.jsをチェックしお、reactの内郚で迷子になりたす... IMO私たちは本圓に誰かからの意芋が必芁です芯。

@seduboisは、通垞のrenderToString関数を䜿甚するのず同じように関数を䜿甚できたす。 ただし、文字列を盎接返すのではなく、文字列に解決されるPromiseを返したす。

したがっお、それを䜿甚するず、次のようになりたす。

var react = require("react");
var renderAsync = require("react-render-async");
var MyComponent = require("./MyComponent");

renderAsync(react.createElement(MyComponent,{some:"props"}).then(function(html){
    console.log(html);
});

理論的には、通垞のrenderToStringず同じ方法で既存のreactコンポヌネントをレンダリングできるはずです。 唯䞀の違いは、非同期コンポヌネントもサポヌトされおいるこずです。

@nmaroその通りです。 それは圹に立ちたす。

これのステヌタスは䜕ですか

@firasdib私たちはただいく぀かの反応

+1

Googleのむンデックス䜜成の問題にはSSRが必芁であり、以䞋に説明するすべおの手荷物は私たちが察凊するためのものであるため、この問題はReactが䞀般的なラむブラリずしお成功するために非垞に重芁です。

JavaScriptが玄束を埅぀適切な方法を提䟛しおいれば、非同期レンダリング党䜓は必芁ないず思いたす。 次に、倩気を瀺すパラメヌタヌを枡すか、デヌタの読み蟌みを同期SSRの堎合たたは非同期実際のWebブラりザヌの堎合にするかどうかを指定できたす。 デヌタ読み蟌みロゞックは、Reactコンポヌネントのコンストラクタヌでpromiseを開始し、componentWillMountで埅機するこずができたす。

しかし、私が理解しおいるように、React開発者はcomponentWillMountの有甚性に疑問を瀺しおおり、コンストラクタヌにすべおの䜜業を行わせるこずを掚奚しおいたす。 どちらの方法でも機胜したす。

䞀郚の人々は、コンポヌネントを玔粋なビュヌにするこずで問題に察凊できるず䞻匵しおいたす。 それらは郚分的に正しいです。 残念ながら、これは、レンダリングツリヌが完了するたでロヌドするデヌタがわからない最も䞀般的なケヌスでは機胜したせん。

問題の栞心は、レンダリング関数がDOMTreeに远加するコンポヌネントを遞択するロゞックを持぀こずができるずいうこずです。 これが、Reactを非垞に匷力にし、サヌバヌ偎のレンダリングに非垞に適しおいる理由です。

IMOの真の解決策は、発行されたすべおのデヌタ読み蟌みの玄束をreactに登録できるようにするこずです。 すべおのデヌタの読み蟌みが完党なreactを玄束するず、レンダリング結果でコヌルバックされたす。 これにはいく぀かの意味がありたす。

  • DOMtreeは数回レンダリングされたす。 これは、䞍安定なデヌタ読み蟌み状態から安定した「読み蟌み枈み」状態に「萜ち着く」ラむブシステムのようなものです。
  • バギヌシステムでは、システムが安定した「ロヌド枈み」状態に到達しないリスクがありたす。 それに察凊するには、タむムアりトを導入する必芁がありたす。

その結果、高速ではないプロセスでサヌバヌ偎のラむブラリをはるかに「蚈算集玄的に」䜿甚するこずになりたす。

したがっお、私はただ物事を成し遂げるこずを支持しお䞀般的なケヌスを劥協する回避策を考えおいたす:)

それたでの間、非同期デヌタ読み蟌み環境でSSRを解決する必芁がありたす。

  1. デヌタ読み蟌み呌び出しは、リク゚ストURLから掟生する必芁がありたすreact-routerが䟋です。 すべおのデヌタ読み蟌みpromiseを1぀のpromiseリストに収集したす。
  2. Promise.allを䜿甚したす。これは、それ自䜓がPromiseです。 このpromiseが完了するず、ロヌドされたデヌタをサヌバヌレンダリング関数に枡したす。

このモデルは、特定の蚭蚈アヌキテクチャに関連付けられおいたせん。 フラックス/ reduxはわずかにメリットがあるようですが、アプリケヌションでreduxモデルを攟棄したため、わかりたせん。

このモデルの問題は、䞊蚘の項目1です。 単玔なアプリケヌションは、すべおのデヌタ読み蟌み呌び出しを認識しおいたす。 独立した「モゞュヌル」を備えた耇雑なアプリケヌションでは、このモデルには、元のReactコンポヌネントツリヌのある皮のレプリケヌション、さらにはレンダリングロゞックが必芁です。

render関数ですでに蚘述されおいるロゞックを繰り返さずに、耇雑なプロゞェクトでSSRを機胜させる方法がわかりたせん。 フラックスは解決策かもしれたせんが、確かに私はそれを経隓しおいたせん。

項目1の実装はあいたいです。 react-routerの䟋では、ルヌタヌずしお、そのルヌトに属する最䞊䜍のコンポヌネントを返す必芁がありたす。 これらのコンポヌネントをむンスタンス化できるず思いたす。

app.use(function(req, res, next) {
    match({ routes, location: req.url }, (error, redirectLocation, renderProps: any) => {
    if (error) {
        res.status(500).send(error.message)
    } else if (redirectLocation) {
        res.redirect(302, redirectLocation.pathname + redirectLocation.search)
    } else if (renderProps) {
        // You can also check renderProps.components or renderProps.routes for
        // your "not found" component or route respectively, and send a 404 as
        // below, if you're using a catch-all route.
        console.log("renderProps", renderProps)
        for (let eachComp of renderProps.components) {
            // create an instance of component
            // ask component to load its data
            // store data loading promise in a collection
            console.log("eachComp: ", eachComp)
        }
        res.status(200).send(renderToString(<RouterContext {...renderProps} />))
        } else {
        res.status(404).send('Not found')
        }
    })
});

したがっお、トップレベルのコンポヌネントはもはや「玔粋な」コンポヌネントではありたせん。 これらのコンポヌネントは、デヌタの読み蟌みをトリガヌする機胜により、トップレベルのコントロヌラヌの圹割を果たしたす。 フラックスモデルはそれを改善したせん。 ルヌトをデヌタ読み蟌み機胜の関連付けに移動しお、別のモゞュヌルに移動するだけです。

残念ながら、トップコントロヌラヌの子にこの方法でデヌタをロヌドし続けるず、reactレンダリングの目的で䜜成されたオブゞェクトグラフが耇補されたす。 物事を単玔に保぀ために可胜であれば、すべおのデヌタの読み蟌みを最䞊䜍のコントロヌラヌレベルに配眮する必芁がありたす。

それが私が芋おいるものです。

これらのSSRの圱響に気付いたずしたら、Googleのむンデックス可胜なアプリケヌションに察するReactの有甚性に぀いお2床考えたこずでしょう。 おそらくfluxは解決策ですが、fluxを䜿甚するず、単玔なReactアプリケヌションよりもアプリケヌション党䜓が耇雑になりたす。 私はそこに行ったこずがある。 単玔なデヌタ読み蟌み機胜の代わりに、耇数のファむルにわたっおロゞックを远跡する必芁がありたす。 理論的なレベルでは、プロゞェクトを実行するたでは本圓に良さそうに芋えたした。 新しい人は始めるのに苊劎したした。 コヌドベヌスからreduxを匕き出した埌は、そのような問題はありたせん。 私はそれがすべおのUIデザむンの耇雑さぞの答えだず思いたした:)

今週のReactConfから、React FiberReact 16がリリヌスされた埌、圌らは次の䜜業を蚈画しおいたすReact 17の堎合ず思われたす。

screen shot 2017-03-16 at 15 55 51

非同期Reactラむフサむクルメ゜ッドが来る可胜性があるこずを意味したすか

さお、ファむバヌは䞻に高速/スムヌズな再レンダリングに関するものではありたせんか サヌバヌでは1回だけレンダリングするため、これらの倉曎がサヌバヌ偎のレンダリングに圱響を䞎えるかどうかはわかりたせん。

@VanCodingは、少し䞍明瞭だった䞊蚘のメッセヌゞを曎新したした。 私はファむバヌがなくなった埌の圌らの蚈画を意味したした。

私のようにここに着陞する人々のために、私は、圹立぀かもしれないreactを䜿甚しおカスタム実装を䜜成するこずになりたした。

https://github.com/siddharthkp/reaqt

キヌは、サヌバヌ䞊でのみ実行されるasyncComponentWillMountです。 ここで説明する問題を回避するために、すべおのコンポヌネントではなく、゚ントリポむントコンポヌネントでのみ䜿甚できたす。

@siddharthkpコンポヌネントが䜕を解決しようずしおいるのか、実際にはわかりたせんか トップレベルのApplicationReactコンポヌネントに察しおasyncComponentWillMountのみをサポヌトしおいる堎合、なぜラむブラリを䜿甚する必芁があるのですか その玄束を倖で解決しおから、renderを呌び出すこずができたすか それずも私は䜕かを逃したしたか

@fkrauthan

その玄束を倖で解決しおから、renderを呌び出すこずができたすか

そうです、たさにそれが行われおいるこずです。

魅力は、1぀のコマンドで非同期ssr+コヌド分割+ hmrを取埗できるこずです。 ssrは簡単ではないので、倚くの人がssrを実装しおいないのを目にしたした。それが動機でした。

トップレベルのApplicationReactコンポヌネントのasyncComponentWillMountのみをサポヌトしたす

  1. 1぀のアプリケヌションコンポヌネントである必芁はありたせん。 各ペヌゞ/画面/゚ントリポむントのデヌタを取埗できたす。 ここで耇数の゚ントリポむントを宣䌝し

  2. このパタヌンは意図的なものであり、ツリヌ内のすべおのコンポヌネントが独自のデヌタを必芁ずする堎合、パフォヌマンスの悪いパタヌンを助長する可胜性がありたす。 トップレベルのコンポヌネントでデヌタを取埗し、小道具ずしお子に枡すず、デヌタが抑制されたす。

@siddharthkpリポゞトリはNext.jsReact Conf BTWでも発衚されたしたよりもどのように改善されおいたすか

https://github.com/zeit/next.js

ずにかく、サヌドパヌティのラむブラリに関する議論はIMHOのトピックから倖れおいたす。私たちが興味を持っおいるのは、React自䜓のサポヌトです。

サヌドパヌティラむブラリに関する議論はIMHOのトピックから倖れおおり、私たちが関心を持っおいるのはReact自䜓のサポヌトです。

同意したす。 reaqtの問題で特定の質問に぀いお話し合うこずができ

これのナヌスケヌスは、react-nativeおよびreact-native-vector-iconsを䜿甚するこずです。 コンポヌネントの小道具は、玄束から受け取ったデヌタによっお決定されるようにしたい

const AsyncUser = props => fetchUser()
  .then(data => (
     <User {...data} />
   ))

サポヌトされおいる堎合、これにより倚くの耇雑なコヌドが理解しやすくなり、新しい非同期パタヌンが開かれる可胜性があるず思いたす。

同じ問題がありたす。ssrを実行しお、予枬プロップだけでなく、componentWillMountのアクションによっおフェッチされたコンテンツも怜玢したす。プロップが準備されるのを埅っおから、プロップを文字列にレンダリングするにはどうすればよいですか。

誰かがこれが䟿利だず思ったら、 react-frontloadずいうラむブラリを䜜成したした。これを䜿甚するず、promise-returning関数をコンポヌネントにバむンドしお、サヌバヌずクラむアントの䞡方のレンダリングでコンポヌネントがレンダリングされるずきに実行できたす。

この関数はサヌバヌレンダリングで「同期的に」実行されたすが実際にはそうではありたせん;-)、最終コンポヌネントのレンダリングは解決されるたでブロックされたす、クラむアントレンダリングでは通垞どおり非同期に実行され、ペヌゞがサヌバヌレンダリング。 コンポヌネントごずに、実行時をよりきめ现かく制埡するために指定できるオプションもありたす。

これはデヌタの読み蟌みに非垞に圹立ちたす-私が解決するために曞いたナヌスケヌスのほずんどです。 やっおみお 😄

https://github.com/davnicwil/react-frontload

<AsyncComponent 
  delayRendering={LoadingComponent}
> 
   {/*return a promise that returns a component here*/}
</AsyncComponent>

デヌタがあるこずがわかっおいるので、䞊蚘のアプロヌチで行う必芁のないすべおの条件付きレンダリングに぀いお考えおみおください。

これに参加したす。 Reactに欠けおいるのはただ重芁な機胜だず思いたす。 たた、サヌドパヌティのラむブラリがこの䞻題をカバヌしおいる堎合でも、これは内郚から盎接行われる必芁があるこずに同意したす。

私は実装を思い぀いたhttps://github.com/timurtu/react-render-async

非垞に優れた非同期コンポヌネントむンタヌフェむス、@ timurtu。

...みなさん、このスレッドに盎接関係するさたざたなこずがあるので、ここでチャむムを鳎らしたいず思っおいたした。このスレッドを長い間远跡しおきたした。

  • 1぀は、SSRを考慮するず、ルヌトレベルのデヌタフェッチが最も理にかなっおいるず思いたす。理由は次のずおりです。
    Redux-First Routerデヌタフェッチ非同期ミドルりェアの80のナヌスケヌスを解決
  • Reduxを䜿甚したサヌバヌレンダリングは今ではばかげたシンプルです。これたでに芋たこずのないように行う方法に぀いお、 Redux-Firstルヌタヌを䜿甚したステップバむステップガむドをサヌバヌ-Pro / wRedux-Firstルヌタヌのように10ステップでレンダリングする
  • 最埌に、コヌド分割を正しく行うには、䞡方぀たり、SSR +分割の䞡方も実行する必芁がありたす。 䞡方を同時に行うこずは倧きな問題であり、少数の人が成功裏に達成し、今たでコミュニティを支揎するための䞀般的なパッケヌゞを持っおいなかったこずがわかりたした。 React Universal Component + babel-plugin-universal-import + webpack-flush-chunks およびextract-css-chunks-webpack-plugin は、この問題を実際に解決するパッケヌゞのファミリヌです。 そしお初めお。 基本的に、サヌバヌ䞊でコンポヌネントを同期的にレンダリングできたすが、さらに重芁なこずに、クラむアント䞊での最初の同期レンダリングのために、レンダリングされた正確なチャンクをクラむアントに転送したす。 webpackプラグむンを介しおcssチャンクスタむルシヌトを取埗するこずもできたす。 これは、 @ timurtuが共有したものや、 main.js読み蟌み、解析、評䟡、レンダリング、そしお最埌に数秒埌に動的むンポヌトを芁求する必芁がある倚くのそのようなコンポヌネントずは異なりたす。 これらは、スタむルなしコンテンツのフラッシュFOUCを解決するための゜リュヌションですが、サヌバヌにレンダリングされた正確なチャンクをペヌゞに埋め蟌むこずはできたせん。 ナニバヌサル私のパッケヌゞファミリヌの名前を䜿甚するず、埓来のWebアプリのように動䜜する同期的な方法で、むンタラクティブTTI短瞮できたす。 あなたはこの蚘事でそれに぀いおもっず孊ぶこずができたす React Universal Component 2.0babel-plugin-universal-import

ルヌトレベルずコンポヌネントレベルの長所/短所に぀いおは觊れおいたせんが、最初のリンクは䞻にそれに焊点を圓おおいたす。 基本的に、デヌタを䞊列ではなく順番にフェッチする必芁があるネストされたコンポヌネントがある堎合、コンポヌネントレベルはSSRに悪圱響を及がしたす。 たた、ルヌトごずに1぀のフェッチしか正しく実行できない堎合は、 componentDidMountで行うのではなく、デヌタの䟝存関係をルヌト゚ンティティにアタッチしおコントラクトを圢匏化するこずをお勧めしたす。 䞊蚘の他の倚くの人がこれず同じ結論に達したした。 Redux-First Routerは、Reduxを非垞に快適に操䜜できるようにする䞀皮の「契玄」に沿っお、これを非垞にうたく圢匏化しおいたす。

Redux-First Routerは、倚くの叀いパラダむムを再び新しくしたすが、驚くべきこずに、Redux゚コシステムに欠けおいる郚分ずしおぎったりず適合したす。 Reduxのワヌクフロヌにネむティブなルヌタヌが必芁な堎合は、Redux-FirstRouterを詊しおみおください。 それは比范的新しく、私はオヌプン゜ヌスの初心者ですが、それは私が基本的に1幎間取り組んできたものであり、それが出おから2か月で倧きな牜匕力を埗たした。 人々はそれを愛しおいたす。 ぜひチェックしおみおください:)。

たた、React Routerよりもはるかに優れたReduxの゜リュヌションであり、残念ながら優れたRedux-LittleRouterが芋逃しおいた方法でビゞョンを正しく実珟する方法を説明するロヌンチ蚘事もありたす。
プレリリヌスRedux-First Router —Redux-Little-Routerを超えた䞀歩

RLRずRFRの䞻な違いは、RFRが垞にLOCATION_CHANGEDだけでなく、ルヌトごずに異なるアクションタむプ぀たり、URLの倉曎をディスパッチするこずです。 これにより、他のアクションず同様に、URLの倉曎をレデュヌサヌの䞀意のタむプずしお切り替えるこずができたす。 小さく芋えるかもしれたせんが、倧きな違いがありたす。 そのため、 <Route />コンポヌネントは必芁ありたせん。これは、Reduxランドでは䞍芁です。 ルヌトthunksでのデヌタフェッチからReact Native、React Navigation、コヌド分割、プリフェッチなど、 Redux-FirstRouterがサポヌトする機胜の膚倧なリストもありたす。

人々の考えを聞きたいです。

@faceyspaceyありがずうございたす。非同期デヌタに基づいお小道具を蚭定する堎合など、私が抱えおいた問題に察凊しおいるず思いたす。たずえば、 react-native-vector-iconsはアむコンを玄束ずしお返すこずができたす。 これは間違いなく別の芋方ですが、非同期コンポヌネントを状態に結び付けるcomponentWillMountたたはredux X_GET_START 、 X_GET_END 、およびX_GET_ERRORアクションボむラヌプレヌトを削枛したす。コンポヌネントをレンダリングするために本圓にそのリク゚ストを1回だけ行いたい堎合。 デヌタのポヌリングなどを行っおいる堎合は、ステヌトフルでreduxを䜿甚する方がおそらく理にかなっおいたす

@faceyspaceyルヌトレベルに぀いおあなたが蚀っおいるこずはわかりたすが、必芁なデヌタのフェッチのみに䟝存し、呚囲の他のすべおを同期的にレンダリングする小さなコンポヌネントを䜿甚する方がよいのではないでしょうか。

より良い どこ React Nativeに぀いお Facebookのような倧芏暡な組織のReactNativeアプリでは

たぶんReactNativeで。 私の芋解にSSRがある堎合、議論はありたせん。 繰り返したすが、フェッチを実行できる1぀のコンポヌネントに制限しない限り、リク゚ストごずに耇数のフェッチがないず、やりたいこずは䞍可胜です。 その時点で、ルヌト゚ンティティずの契玄を圢匏化するこずをお勧めしたす。

React NativeずSPAに぀いおは、確かに。 しかし、デヌタデップが組み蟌たれおいるコンポヌネントをテストするのは面倒です。 Apolloにはここにいく぀かのものがありたすが、最埌に、デヌタペアのコンポヌネントテストを本圓に正しく、぀たりシヌムレスにするために、長いToDoリストがあるこずを確認したした。 セットアップずモックが簡単なストアが1぀あるセットアップが奜きです。 すべおのテストでそれを行う方法を再利甚できたす。 次に、そこからコンポヌネントをテストするのは、スナップショットを取埗する単玔な同期レンダリングです。 コンポヌネントにデヌタディップを远加するず、Reactのテストは盎感的ではなくなりたす。 しかし、人々はそれを行い、それを自動化したす。 暙準が少なくなり、カスタムアドホックコヌドに近づきたした。 移入する必芁のある非同期コンポヌネントごずに異なる戊略を立おるよりも、非垞に明癜な方法で非同期に移入できるストアを甚意する方が生産性が高くなりたす。

SSRがなく、テスト戊略がシヌムレスで邪魔にならない堎合は、コンポヌネントレベルに反察したせん。 あなたがメガコヌプであるなら、それは理にかなっおいたす。なぜなら、すべおの開発者がトップルヌトレベルに觊れる必芁がなく、他の人のためにそれを壊す可胜性があるからです。 そのため、FBはRelayずGraphQLを䜿甚しおこのルヌトを開拓したした。 問題の事実は、䞖界で100瀟だけが本圓にこの船に乗っおいるようなものです。 ですから、私はコロケヌションをほずんどの人/アプリ/䌁業にずっお珟実よりも誇倧宣䌝だず考えおいたす。 ルヌトレベルのコツを぀かみ、Redux-First Routerのように非垞にうたく機胜するパッケヌゞを入手するず、メンバヌがルヌトレベルに觊れるこずを蚱可されおいるチヌムのアプロヌチを開発するのがはるかに簡単になり

https://www.codesandbox.io

基本的に、それがどのように行われるかを理解したら、私はあなたの意芋を聞きたいです。 これはSPAであるこずに泚意しおください。 したがっお、SSRの䟋に぀いおは、デモリポゞトリたたは定型文を確認する必芁がありたす。 しかし、これは良いスタヌトです。

最も簡単な方法は、非同期レンダリングメ゜ッドをサポヌトするこずだず思いたすレンダリングはpromiseを返したす。 これにより、ルヌトコンポヌネントが子コンポヌネントのレンダリングを埅機できるようになり、もちろんレンダリングの結果が玄束されたす。 私はここでpreactにこのようなものを実装したしたhttps://github.com/3axap4eHko/preact-async-example

@faceyspacey䞊蚘の詳现な回答ありがずうございたす。 私はRedux-FirstRouterのアむデアが本圓に奜きです。それは間違いなく私のすべおの問題を解決し、以前よりもはるかに透明でクリヌンなものになりたす。

本圓にありがずう

@raRaRaあなたがそれを気に入っおくれおうれしいです ...最倧の課題の1぀は、これたでルヌトレベルのデヌタフェッチの適切な抜象化が行われおいなかったこずです。 React React v3にはコヌルバックがあり、v4には優れたパタヌンがありたす特にreact-router-configパッケヌゞの堎合が、v4では自明ではなく、ファヌストクラスではありたせん。 それは埌付けです。 ただし、さらに重芁なのは、Reduxには存圚しないこずです。 したがっお、reduxナヌザヌが完党な「ルヌトレベル」の抜象化を利甚できるようになったのは、これが初めおです。

RFRでは、「ルヌトレベル」ず「コンポヌネントレベル」の重芁性が再考されるず思いたす。 RelayやApolloのようなものは、コンポヌネントぞのデヌタ䟝存関係のペアリングに関しお倚くの誇倧宣䌝を生み出したしたが、これら2を䜿甚しおいない堎合、ラむフサむクルハンドラヌで䜕かを行うこずによっお、ある時点で傷぀いた䞖界に陥る可胜性がありたす。 。

ずはいえ、最終的にRFRはApolloずルヌトレベルで統合される予定です。 前述のたれな䟋倖を陀いお、コンポヌネントレベルで物事を行うこずによるメリットはほずんどありたせん。 少なくずも80の時間そしおおそらくアプリでは100、ルヌトに基づいお必芁なすべおのデヌタを決定できたす。 それが䞍可胜な堎合は、「ビュヌレむダヌ」でデヌタを取埗しおいるため、URLによっおすべおが解釈されるように再考される可胜性がありたす。 そのため、Apolloのようなツヌルを䜿甚しおも、問題のあるアンチパタヌンに取り組み始めたす。これにより、「状態」をビュヌレむダヌ以倖の堎所に配眮しないこずで、最終的には痛みを匕き起こす可胜性がありたす。 ぀たり、これらのデヌタフェッチを実行するために必芁な状態です。 倚くの堎合、デヌタのフェッチに䜿甚される正確なパラメヌタヌを調敎する必芁がありたす。 したがっお、デヌタをフェッチする盎前に、状態ず小道具を取埗し、2を倉換しおパラメヌタを取埗したす。 これは、珟圚ビュヌレむダヌに存圚し、その再レンダリングメカニズム぀たり、ラむフサむクルハンドラヌが呌び出されるずきの察象ずなるものです。 ある時点たたは別の時点でのすべおのアプリは、受信/倉曎された無関係の小道具に応じお、デヌタがフェッチされるべきずきにフェッチされない、たたはフェッチされないずいう結果になりたす。 たた、すべおのアプリで、倉曎された無関係の小道具を防ぐために远加のコヌドを䜜成する必芁がありたす。 ぀たり、デヌタのフェッチに䜿甚されるパラメヌタに圱響を䞎えない小道具。

React Native + Apolloの堎合、SSRがないため、サヌバヌで順次デヌタフェッチが発生する可胜性があるため、問題は少なくなりたす。 ただし、画面が非垞に小さい堎合、コンポヌネントレベルのデヌタフェッチが本圓に必芁ですか。 あなたは䞀般的に、それぞれの「シヌン」がそのデヌタに関しお䜕を必芁ずしおいるかを知っおいたす。 これは、100䞇個のグラフ、耇数のテヌブルなどを備えたデスクトップWebパネルダッシュボヌドのようなものではありたせん。その1぀のナヌスケヌスは、コンポヌネントレベルが意味をなし始める最倧の䞻芁な堎所です。 ただし、そこでも、これらすべおのりィゞェットのすべおの芁件を1぀の堎所で指定し、Apolloを介しおそれらをフェッチできたす。 ただ十分に考えおいたせんが、基本的な考え方は、GraphQLデヌタ芁件をルヌトにアタッチしおから、他のReduxデヌタず同じようにコンポヌネントでデヌタに接続するこずです。 ぀たり、より具䜓的には、react-reduxのconnectずApolloの同等のものの䞡方を排陀するずいう考え方です。 1぀だけ欲しいのですが、もっずフラットにしたいのです。 Apolloを䜿甚するには、コンポヌネントに本圓に必芁なものにアクセスするために、より深くネストされたデヌタを砎棄する必芁がありたす。 ビゞョンは、通垞のReduxず同じように芋える1぀の方法に加えお、ルヌトレベルでのgraphql仕様です。

私はほずんど調べおいないので、それに぀いお話すのは少し時期尚早ですが、ルヌトレベルがアプリの正しいアプロヌチである堎合、Apollo + GraphQLも䟋倖ではありたせん。

最埌に、すべおのデヌタ䟝存性ず非同期䜜業がコンポヌネントから分離されおいる堎合、テストは非垞に簡単です。 関心の分離は、デヌタフェッチに぀いお心配するこずなくコンポヌネントをテストできる堎合、生産性を倧幅に向䞊させたす。 もちろん、テストでは、事前に非同期フェッチを実行しおストアにデヌタを入力する必芁がありたすが、コンポヌネントから分離しおおくず、すべおのテストで事前に䜿甚するいく぀かのsetupヘルパヌ関数の䞋でそのような䜜業を簡単に圢匏化できたす。コンポヌネントがどのようにレンダリングされるかをテストする前に、ストアにデヌタを入力したす:)

@faceyspacey私は完党に同意したす。 しかし、私はApolloもGraphQLも詊したこずがないこずを認めなければなりたせん。私はそれらを確実にチェックしお、それらが私のナヌスケヌスにどのように適合するかを確認したす。

私はMVCパタヌンを䜿甚しおWebアプリケヌションを䜜成するこずに非垞に慣れおいたす。ここでは、基本的にすべおのデヌタずコントロヌラヌぞの䟝存関係を取埗したす。 次に、デヌタをビュヌたたはビゞネスロゞックに挿入したす。 あなたが蚀ったように、それはビュヌがデヌタフェッチず結合されおいないのでテストをはるかに簡単にしたす。

ビュヌ郚分がデヌタをフェッチしおビゞネスロゞックを実行しおいるMVCアプリケヌションを芋たこずがありたすが、それはひどいものです。 䞀郚のビュヌ/コンポヌネントに隠されおおり、テストが困難/䞍可胜になるため、どちらのデヌタがフェッチされるかわかりたせん。

私にずっお、Redux-First Routerは、MVCのコントロヌラヌ郚分ずルヌトに非垞によく䌌おいたす。 これはずおも理にかなっおいたす:)

ありがずう。

結局のずころ、新しいスタックは次のずおりです。

Mリダックス
V反応する
C Redux-最初のルヌタヌたもなく「Rudy」に名前が倉曎されたす

React特にReduxが登堎したずき、私たちは皆、MVCの叀代の知恵を捚おたいず思っおいたようでした。たるで、以前のアプリケヌションを開発する際の苊痛を完党に取り陀くこずができたかのようでした。 しかし、最終的には、それをサポヌトするためのツヌルがただ構築されおいないだけだず思いたす。 結局のずころ、リアクティブなクラむアントファヌストのアプリケヌションであっおも、MVCの恩恵を倧いに受けおいたす。

新しいクラむアントファヌストスタックず埓来のサヌバヌサむドMVCでは動䜜が少し異なる堎合がありたすが、基本的には同じ3぀の関心の分離です。

3぀の盞互䜜甚/動䜜の違いに぀いおは、基本的に、これたでコントロヌラヌは初期段階でモデルを取埗し、それらを䜿甚しおビュヌをレンダリングしおいたした。 そしお今では、コントロヌラヌRFRがすぐにビュヌをレンダリングし「UIモデル」、぀たりRedux状態で遞択、コントロヌラヌがドメむンモデルこれもRedux状態で保存されおいるを芋぀けたら、ビュヌをもう䞀床

こんにちはみんな、このリンクを芋おください。 これがデヌタサヌバヌ偎のレンダリング䟋ですhttps://github.com/bananaoomarang/isomorphic-redux

@ harut55555 idkそれは私だけかもしれたせんが、これはgetリク゚ストずpostリク゚ストを行うための倚くのコヌドのようです

䜕か倉曎はありたすか リリヌスされた16の反応ずほずんどの゜リュヌションが機胜しない

珟圚のアプロヌチは、reduxobservableやreduxthunkなどのツヌルでreduxを䜿甚するこずだず思いたす

私の䜿甚䟋

<App>
    <Page>
        <AsyncModule hre="different.com/Button.react.js" /> downloaded from external url on server or client
    </Page>
</App>

問題は、アプリをレンダリングする前に、どのようなコンポヌネントを䜿甚するかわからないこずです。

奜奇心旺盛なコンポヌネントではなく、デヌタ/コンテンツをダりンロヌドしおみたせんか

い぀ 動的ペヌゞがあり、コンポヌネントはそうである堎合ずそうでない堎合がありたす

条件付きレンダリングが必芁なようですhttps://reactjs.org/docs/conditional-rendering.html

ルヌティングの問題だず思いたす。reactはペヌゞをレンダリングするだけで、レンダリングデヌタを管理および芁求するべきではありたせん。

Apolloの@graphqlを䜿甚するず、デヌタの読み蟌みが非垞に簡単になり、React-Router v4コンポヌネントベヌスのAPIを䜿甚するず、シンプルなコンポヌザブルルヌティングが可胜になりたす。 どちらもReduxのアプリケヌション状態に盎亀しおいたす。

デヌタのフェッチを埅機するシングルパスストリヌミングレンダリングを実行するには、 render()がpromiseを返すこずができる必芁がありたすクラむアントでは、今ず同じように、サヌバヌでのみpromiseを返したす。

次に、 @graphqlは、デヌタがロヌドされた埌、renderのpromiseを返すこずができたす。 残りはすべお単玔なReactです。

数ヶ月前、私はJSConfアむスランドで、Reactの今埌の非同期レンダリング機胜に぀いお説明したした第2郚を参照 https //reactjs.org/blog/2018/03/01/sneak-peek-beyond-react

@acdliteは、同じ抂念を適甚しお、Reactコンポヌネントでサヌバヌ䞊のデヌタを非同期的に埅機し、準備ができたらマヌクアップを段階的にフラッシュする方法に぀いお説明したした https 

これらの講挔をお楜しみください。 1幎かそこらでこの問題を終わらせ、これに察する公匏の戊略を立おるこずができるかもしれないず思いたす。

リングを芚えおいたす。 私たちは結婚しお未来を䞀緒に蚈画しおいたす。 今これを終わらせお、私に䌚いに来おください。 働く時間はい぀も愛

ReactDOMServer.renderToStaticMarkupを䜿甚しおツリヌをりォヌクし、非同期の䟝存関係に到達する堎所にブックマヌクを配眮し通垞、APIからデヌタをロヌド、ツリヌ党䜓が解決されるたで、これらの䟝存関係が解決されるたでツリヌをりォヌクし続けるこずができたす。次に、最埌のReactDOMServer.renderToStringを実行しお、実際にHTMLにレンダリングしたす。これは、すべおの䟝存関係が解決されたため、同期されたす。

私はreact-baconjs  render-to-html.jsでこのアプロヌチを採甚し@gaearonのコメントに觊発されたした。

@ steve-taylorええ、これは機胜したす。 これは、 react-frontloadで䜿甚する回避策でもありたす。これは、Reactアプリで機胜する、これに察するより汎甚的な゜リュヌションです。

基本的に、同期レンダリングロゞックを2回実行し、最初のレンダリングでヒットしたすべおのデヌタ読み蟌みの玄束が解決されるのを埅っおから2番目のレンダリングを実行するこずで、非同期レンダリングを停造しおいるだけです。

明らかに少し無駄がありたすが、十分に機胜したす最初のレンダリングの出力は単なる玄束ではなく、実際のHTMLでもありたす。 真の非同期サヌバヌレンダリングがReactに組み蟌たれるず、驚くべきこずになりたす。

@davnicwilいい仕事 特定の非同期SSR゜リュヌションを䞀般化するこずを考えたした。 react-frontloadは無制限の非同期深床を凊理したすか あなたが「二床」ず蚀ったので尋ねる。

@ steve-テむラヌ也杯 はい、深さでツリヌ内のコンポヌネントの深さを意味する堎合、それは無制限です。 これにより、コンポヌネント自䜓で高階コンポヌネントを䜿甚しおデヌタ読み蟌み関数を宣蚀し、最初のレンダリングでそれが発生するず、実行されおPromiseが収集されたす。

動䜜しないのは、デヌタを非同期でロヌドする子コンポヌネントがさらにあり、それが理にかなっおいる堎合は、結果に応じお動的にレンダリングされる堎合です。 これは、この皮のネストが発生しないようにアプリを構成する必芁があるこずを意味したす。実際には、これは倧きな制限ではありたせん。 実際、倚くの点で、ネストされた非同期ロゞックはシリアルリク゚ストを意味し、埅機時間が長くなるのに察し、フラット化はパラレルリク゚ストを意味するため、UXに関しおは優れおいたす。

ずはいえ、ネストの問題実際には、この非同期サヌバヌのレンダリングの問題党䜓は、近い将来、Reactに登堎するSuspenseのもので解決される可胜性がありたす。 🀞

参考たでに、これに取り組み始めたした。

https://reactjs.org/blog/2018/11/27/react-16-roadmap.html#suspense -for-server-rendering

玠晎らしい@gaearon

@davnicwil react-baconjsは無制限の深さをサポヌトしたす。

@gaearonこれにより、create-subscriptionでオブザヌバブルをサポヌトできるようになり、オブザヌバブルの

この機胜が欲しいのは2぀の理由からです。 たず、私のアプリでは、状態はWebワヌカヌに保存されたす。 したがっお、コンポヌネントに必芁なその状態のビットを取埗するこずは非同期操䜜ですが、5ミリ秒ほどかかり、デヌタを埅っおいる間にReactが䜕かをレンダリングするこずは意味がありたせん。 次に、珟圚、オブザヌバブルをコンポヌネントに倉換する普遍的な方法はありたせん。オブザヌバブルが最初の倀を同期的に出力する堎合は、サブスクラむブしおその倀を取埗し、サブスクラむブを解陀しおから、再床サブスクラむブしお倉曎をリッスンしたすこれがリプレむです。 create-observableドキュメントの件名の䟋。 たた、最初の倀を非同期で出力する堎合は、最初にnullをレンダリングし、倉曎をリッスンしたす。

@ steve-taylor react-frontloadは、 1.0.7リリヌスで、無制限の深さのコンポヌネントネストもサポヌトするようになりたした。

このラむブラリがこのスレッドにたどり着く䞀郚の人々に圹立぀こずを願っおいたす-クラむアント/サヌバヌレンダリングで動䜜する非同期デヌタ読み蟌み゜リュヌションを探しおいる堎合は、最小限の統合䜜業でそれをチェックする必芁がありたす。

アプリがReactHooksでビルドされたずきにこの問題が発生し、それを解決するためにパッケヌゞreact-use-apiを䜜成したした。これは、APIデヌタをフェッチしおSSRをサポヌトするカスタムフックです。 パッケヌゞが困っおいる人に圹立぀こずを願っおいたす。

ただし、ただ公匏の解決策を埅぀こずを楜しみにしおいたす。react-frontloadが蚀うように、珟圚レンダリングが開始されるず非同期デヌタの読み蟌みが行われるのを埅぀組み蟌みの方法はありたせん。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡