私のデータベースには、素敵な小さなリストにレンダリングしたい動物の配列があります。ユーザー エクスペリエンスを向上させるために、(新しいserver-render
パッケージを使用して) サーバー上でレンダリングし、 react-meteor-data
( withTracker
) を使用して変更をサブスクライブしたいと考えています。
現在、これは1つのことを除いて機能しています。サーバーはコンテンツ (データを含む) を期待どおりにレンダリングし、クライアントに送信します。問題はクライアントにあります。
ページが読み込まれると、meteor はデータ接続をセットアップし、ページをレンダリングします。この最初のレンダリングは、データ接続がデータを返す前に発生するため、動物の空のリストがレンダリングされます (サーバーでレンダリングされたリストが上書きされ、警告が発生します)。次に、データが到着すると、リストは完全に (再) レンダリングされます。
これにより、リストが点滅してから戻るため、ユーザー エクスペリエンスがかなり低下します。データが利用可能になるまで、クライアント レンダリングを延期したいと考えています。これは可能ですか?
私のコードは本当にシンプルで、次のようになります。
リスト コンポーネント:
import React, { Component } from 'react';
import { withTracker } from 'meteor/react-meteor-data';
import { AnimalsData } from '../api/animals';
class Animals extends Component {
render() {
const {animals} = this.props;
console.log(animals);
return <ul>
{animals.map(animal =>
<li key={animal._id}>
{animal.name}
</li>)
}
</ul>
}
};
// Load data into props, subscribe to changes on the client
export default withTracker(params => {
if (Meteor.isClient) {
// No need to subscribe on server (this would cause an error)
Meteor.subscribe('animals');
}
return {
animals: AnimalsData.find({}).fetch()
};
})(Animals);
サーバ:
import React from "react";
import { renderToString } from "react-dom/server";
import { onPageLoad } from "meteor/server-render";
import Animals from '../imports/ui/Animals';
import '../imports/api/animals';
onPageLoad((sink) => {
sink.renderIntoElementById('app', renderToString(<Animals />));
});
クライアント:
import React from 'react';
import ReactDOM from "react-dom";
import { onPageLoad } from "meteor/server-render";
import AnimalList from '../imports/ui/Animals';
onPageLoad(sink => {
ReactDOM.hydrate(
<AnimalList />,
document.getElementById("app")
);
});
データベース:
import { Meteor } from 'meteor/meteor';
import { Mongo } from 'meteor/mongo';
export const AnimalsData = new Mongo.Collection('animals');
if (Meteor.isServer) {
Meteor.publish('animals', () => {
return AnimalsData.find({});
});
}
何が起こるか (Animals.jsx の console.log):
- サーバー上でレンダリング [動物データ]
- データが到着する前にクライアントでレンダリングします。これにより、サーバーでレンダリングされたリストが削除されます []
- データ到着時にクライアント上でレンダリング [動物データ]