これが慣用的な React ではないことはわかっていますが、レンダリング前とレンダリング後の両方でダウンストリームの仮想 DOM の変更を通知する必要がある React コンポーネント (逆スクロールビュー) に取り組んでいます。
これを説明するのは少し難しいので、出発点である JSFiddle を作成しました: https://jsfiddle.net/7hwtxdap/2/
私の目標は、ログを次のようにすることです。
Begin log
render
rendered small
rendered small
rendered small
before update
rendered big
after update
before update
rendered big
after update
before update
rendered big
after update
React が DOM の変更をバッチ処理することがあることは承知していますが、それで問題ありません (つまり、ログ イベントはbefore update; rendered big; rendered big; after update; ...
.
https://jsfiddle.net/7hwtxdap/4/で行うように、コールバックを指定することで手動で動作を近似できます。ただし、このアプローチはスケーリングしません。たとえば、子ではなく子孫からイベントをバブリングさせる必要があります。私が使用するすべてのコンポーネントにこれらの種類のイベント ハンドラーを追加する必要はありません。
使用事例:
メッセージ用の「逆スクロール コンポーネント」の作成に取り組んでいます (新しい要素が追加されたり、既存の要素のサイズが変更されたりすると、スクロール変更の基準は、すべてのメッセージング アプリの上部 ala ではなく、コンテンツの下部になります)。動的に変更された子があります (クラスに似てい<MyElement />
ますが、高さが可変で、ajax からのデータなどがあります)。これらは、Flux のような状態ストアからデータを取得するのではなく、pub-sub データ同期モデルを使用しています (setTimeout() でかなりうまく近似されています)。
逆スクロールを機能させるには、次のようにする必要があります。
anyChildrenOfComponentWillUpdate() {
let m = this.refs.x;
this.scrollBottom = m.scrollHeight - m.scrollTop - m.offsetHeight;
}
anyChildrenOfComponentDidUpdate() {
let m = this.refs.x;
m.scrollTop = m.scrollHeight - m.offsetHeight - this.scrollBottom;
}
この設計にとって重要なのは、「反転スクロール対応」ではない他の要素の周りに要素をラップできるようにすることです (つまり、反転スクロール ハンドラーに変更されたことを通知する特別なコードは必要ありません)。