Reactjs Redux服务器端呈现:操作
我正在构建一个带有Reactjs Redux服务器端呈现:操作,reactjs,redux,isomorphic-javascript,server-side-rendering,Reactjs,Redux,Isomorphic Javascript,Server Side Rendering,我正在构建一个带有React和Redux的通用应用程序,它通过NodeJS和ExpressJS在服务器端呈现 一切正常,Express处理程序从“react router”调用{match},每次都将创建一个新存储实例 我遇到的问题是:{renderToString}来自'react dom/server'的{renderToString}只呈现存储的原始版本,如果存储发生了变化(例如:通过组件发送的操作将装载)存储将被更新,但在调用新的renderString之前,生成的标记不会更改 我不知道
React
和Redux
的通用应用程序,它通过NodeJS
和ExpressJS
在服务器端呈现
一切正常,Express处理程序从“react router”调用{match},每次都将创建一个新存储实例
我遇到的问题是:{renderToString}来自'react dom/server'
的{renderToString}只呈现存储的原始版本,如果存储发生了变化(例如:通过组件发送的操作将装载)存储将被更新,但在调用新的renderString
之前,生成的标记不会更改
我不知道(每个请求)还原程序将如何更改状态,因此,在调用renderToString
之前,我无法提供初始状态
我希望避免进一步的renderToString
调用
这是我的示例代码:
const store=createStore(
减速器,
//提供初始泛型状态的对象
res.viewModel.uu初始状态uu124; |对象.create(null),
中间件
);
//现在,存储是原始的,正在调用store.getState()
//我将检索状态的无效版本
常量标记=renderToString(
{}
);
//现在存储已正确计算并调用
//获取正确的版本,但标记
//它仍然很旧。只有调用“renderToString”才能获得
//正确的标记
常量markup2=renderToString(
{}
);
一种方法是在路由组件上提供一个按路由操作作为静态方法,然后在调用renderToString
之前由express中间件调用,例如
类索引扩展组件{
componentDidMount(){
//注意:客户端在'componentDidMount'而不是'componentWillMount'中获取数据,以确保我们不会在服务器上重复工作。
const{dispatch}=this.props;
Index.fetchData({dispatch});
}
render(){
...
}
}
Index.fetchData=函数({dispatch}){
//通过redux thunk/redux promise返回承诺
返回分派(fetchDataIfRequired());
};
导出默认连接(state=>state)(索引);
然后,在您的中间件中,您将在呈现之前调用匹配路由组件上定义的所有静态fetchData
方法,例如
app.use((请求、回复)=>{
匹配({
路线,
位置:req.url
},(错误,重定向位置,渲染器操作)=>{
const store=configureStore();
const requests=renderProps.components
.map(组件=>{
//处理“连接”的组件。
if(component.WrappedComponent){
component=component.WrappedComponent;
}
if(component.fetchData){
返回component.fetchData({
发货:商店发货
})
.catch(()=>{});
}
});
承诺。所有(请求)
.然后(()=>{
//存储现在包含所有必需的状态。
常量标记=renderToString(
);
res.send(`${markup}`);
});
});
});
您可以在中看到一个完整的示例
相关模块:
另一种方法:
使用Redux传奇
赞成的意见
避免特定的服务器端
附加代码
阻碍了重演
欺骗
调用renderToString
两次
例如:
从'redux saga'导入{END};
store.runSaga=sagaMiddleware.run;
store.close=()=>store.dispatch(结束);
//server.js
store.runSaga(sagas).done.then(()=>{
const state=store.getState();
const html=renderToString(rootComponent);
回复(renderApplication({state,html}));
});
renderToString(rootComponent);
store.close();
我看到了这种方法,但我更喜欢redux saga
方式,因为它避免了静态方法的必要性
@Hitmands您能分享redux saga
方法吗?我添加了参考作为答案。我不理解这一点。如果调用store.close()代码>在执行回调之前,它将调用传奇中的END
事件,因此不会发生任何事情?