在我的数据库中,我有一组动物,我想将它们渲染成一个漂亮的小列表。为了改善用户体验,我想在服务器上渲染它(使用新包),然后使用( )server-render
订阅任何更改。react-meteor-data
withTracker
现在,除了一件事之外,这是可行的。服务器按预期呈现内容(包括数据),然后将其发送到客户端。问题出在客户端。
页面加载后,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):
- 在服务器上渲染 [动物数据]
- 在数据到达之前在客户端呈现。这将删除服务器上呈现的列表 []
- 数据到达时在客户端呈现 [动物数据]