gpt4 book ai didi

meteor ,服务器渲染 withTracker。推迟客户端渲染

转载 作者:行者123 更新时间:2023-12-02 04:31:15 26 4
gpt4 key购买 nike

在我的数据库中,我有一组动物,我想将它们渲染成一个漂亮的小列表。为了改善用户体验,我想在服务器上呈现它(使用新的 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):

  1. 在服务器上呈现 [动物数据]
  2. 在数据到达之前呈现在客户端上。这将删除服务器上呈现的列表 []
  3. 数据到达时在客户端呈现[动物数据]

最佳答案

您可以在订阅准备就绪之前延迟对页面进行补水。

例如,假设您有一组链接

import { Mongo } from 'meteor/mongo';
import { Meteor } from 'meteor/meteor';

export default Links = new Mongo.Collection('links');

if(Meteor.isServer) {
Meteor.publish('links', () => {
return Links.find({});
});
}

client/main.js 中,您将订阅该发布,并等待它准备就绪,然后再继续您的水合作用。您可以使用 meteor/tracker 来做到这一点,因为 ready() 是一个可观察对象。

import React from 'react';
import ReactDOM from 'react-dom';
import { Meteor } from 'meteor/meteor';
import { onPageLoad } from "meteor/server-render";
import App from '../imports/ui/entry_points/ClientEntryPoint';
import { Tracker } from 'meteor/tracker';

onPageLoad(async sink => {
Tracker.autorun(computation => {
if(Meteor.subscribe('links').ready()) {
ReactDOM.hydrate(
<App />,
document.getElementById("react-target")
);
computation.stop();
}
})
});

显然,这需要订阅整个应用程序中的所有内容,但您可以添加额外的逻辑来根据路由订阅不同的内容。

关于 meteor ,服务器渲染 withTracker。推迟客户端渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48567599/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com