我正在使用流星的服务器渲染包中用React路由器V4,但我得到了一个typeError,that Meteor.subscribe不是一个函数,我无法弄清楚为什么会发生这种情况或什么是错误的
这是我在客户端上的代码:
import React from 'react';
import { Meteor } from 'meteor/meteor';
import { render } from 'react-dom';
import {RenderRoutes} from '../imports/api/routes.jsx'
import { onPageLoad } from 'meteor/server-render';
import ReactDOM from 'react-dom';
import {
Router,
Route,
Link,
Switch
} from 'react-router-dom'
import createBrowserHistory from 'history/createBrowserHistory'
const history = createBrowserHistory()
const Application = () => (
<Router history={history}>
<RenderRoutes/>
</Router>
);
onPageLoad(()=> {
ReactDOM.render(<Application/>, document.getElementById('react-root'));
});
和在服务器上:
onPageLoad((sink) => {
const context = {};
const App = props => (
<StaticRouter location={props.location} context={context}>
<RenderRoutes/>
</StaticRouter>
);
sink.renderIntoElementById('app', renderToString(<App location=
{sink.request.url} />));
});
我能够使用上述非常简单的应用程序正确地工作,正是订阅和createContainer带来了错误,是否有一种单独的方式来处理它们?
这是我在客户上订阅的方式:
export default createContainer(() => {
const handle1 = Meteor.subscribe('categories');
const handle2 = Meteor.subscribe('subcategories');
const handle3 = Meteor.subscribe('products');
const isReady1 = handle1.ready()
const isReady2 = handle2.ready()
const isReady3 = handle3.ready()
return {
products: isReady3 ? Products.find({}).fetch() : [],
categories: isReady1 ? Categories.find({}).fetch() : [],
subcats: isReady2 ? SubCategories.find({}).fetch(): [],
};
}, B2C);
如果您能弄清楚发生了什么或我犯的错误,那将是很棒的谢谢
删除所有订阅并添加自动发布后,它工作正常,但是我认为这不是一个不当的解决方案,因为我不希望在任何地方发布所有数据?
解决:我将所有订阅都放在Meteor.isclient块中,因此,即使客户端上存在代码,并且一个人将其用于服务器范围,即即使是Meteor.isclient Block,也不应在服务器上运行。为可能导致服务器渲染错误
另一个解决方案是通过将Meteor.subscribe
添加为返回具有ready
函数的对象的函数,以返回true
:
服务器端:
onPageLoad(sink => {
const context = {};
// monkey patching subscribe on the server to be ready immediately
Meteor.subscribe = (topic) => ({ready: () => true});
sink.renderIntoElementById("app", renderToString(
<StaticRouter location={sink.request.url} context={context}>
<App />
</StaticRouter>
));
});
这样,您就无需单独触摸每个组件。