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
    事件,因此不会发生任何事情?