redux onEnter dispatch可以在服务器渲染上工作吗?

时间:2016-02-04 14:45:31

标签: node.js express reactjs redux

我有一个使用redux-router的有效客户端应用。  我从我的api发送user页面的初始状态。

我的路线档案:

export default function ({ dispatch, getState }) {
    function getUser(nextState, replaceState) {
        dispatch(getUserData(nextState.params.id));
    }

    return (
        <Route path="/" component={App}>
            <Route path="user/:id" component={User} onEnter={getUser}/>
                <Route path="*" component={NoMatch}/>
            </Route>
        );
    }
}

所以在客户端它运作良好。 我希望在getUserData调度返回数据后将标记渲染为字符串。

这就是我的服务器匹配和渲染(来自官方服务器渲染示例):

app.use((req, res) => {
    const store = reduxReactRouter({ routes, createHistory: createMemoryHistory })(createStore)(reducer);
    const query = qs.stringify(req.query);
    const url = req.path + (query.length ? '?' + query : '');

    store.dispatch(match(url, (error, redirectLocation, routerState) => {
        if (error) {
            console.error('Router error:', error);
            res.status(500).send(error.message);
        } else if (redirectLocation) {
            res.redirect(302, redirectLocation.pathname + redirectLocation.search);
        } else if (!routerState) {
            res.status(400).send('Not Found');
        } else {
            res.status(200).send(getMarkup(store));
        }
    }));
});

使用onEnter时是否可以正常工作? 或者它只在浏览器上触发?

非常感谢任何有帮助的人! 感谢

1 个答案:

答案 0 :(得分:1)

我不明白 - 我认为getUser是异步的,渲染在React中始终是同步的。您必须提前获取数据。依赖onEnter是一个不错的主意,但它不起作用。

基本上...

首先:您需要公开抓取数据的方法,以便可以在服务器之外调用它们。动作/调度程序/存储在请求/响应循环中不能很好地工作,并确保您有一个包含API调用的文件。

第二步:将所有路由放在JSON文件中,React Router(或任何路由器)读取该JSON并将路由与其处理程序一起添加到循环中,服务器端代码读取这些路由并为其添加快速路由指向该方法的路由,JSON中的每个路由还包含对该组件所需的数据的引用 real 初始呈现(异步调用)。您创建了初始状态对象的空副本,快捷方的每个处理程序执行对相关API方法(来自JSON)的所有调用,并且当Promise.all解析“获取数据并将其填入州“解决你渲染,

渲染现在包含相关数据。

第三,你需要弄清楚如何将状态传递给服务器,用户如何登录,他们可以做什么等等 - 我建议让第二台服务器充当缓存,因为渲染在React中受CPU限制所以你需要缓存。我们根据路线,用户状态,设备和一些其他基本内容进行缓存。

第四,你将非渲染服务器(缓存一个)指向渲染服务器并转发请求,希望请求应该到达缓存,你需要让非渲染服务器“退回”到客户端渲染仅当渲染服务器失败时。这也允许您在部署时“热交换”渲染服务器。

你还需要一些方法来从渲染服务器提供JavaScript本身(所以有一个单一的事实来源)不应该是一个大问题。

流程中有更多精致的部分 - 但这就是我们如何做到这一点,我们有亚秒完整渲染,我觉得很好。当我们的网站主要是Angular并在客户端渲染时,从5秒开始下降。