繁体   English   中英

使用 redux 和 react 的异步服务器端渲染

[英]Async server-side rendering using redux & react

我在使用ReactReduxRedux-ThunkReact-Router获得有效的服务器端渲染解决方案时遇到了严重的困难。

目前,我的解决方案在客户端遵循基本准则和这篇文章: https : //codepen.io/stowball/post/a-dummy-s-guide-to-redux-and-thunk-in-反应 为简单起见,我将使用该博客中的代码作为示例。 唯一的改变是我添加了一个console.log("X"); 到减速器功能items以便我知道何时调用它。 结果函数是:

export function items(state = [], action) {
    switch (action.type) {
        case 'ITEMS_FETCH_DATA_SUCCESS':
            console.log('X');
            return action.items;

        default:
            return state;
    }
}

我还设置了itemsFetchData函数来返回承诺,变成:

export function itemsFetchData(url) {
    return (dispatch) => {
        dispatch(itemsIsLoading(true));

        return fetch(url)
            .then((response) => {
                if (!response.ok) {
                    throw Error(response.statusText);
                }

                dispatch(itemsIsLoading(false));

                return response;
            })
            .then((response) => response.json())
            .then((items) => dispatch(itemsFetchDataSuccess(items)))
            .catch(() => dispatch(itemsHasErrored(true)));
    };
}

因为我需要服务器端渲染。 我设置 Express 来使用我的中间件handleRender ,它反过来调用返回 HTML 字符串的renderFullPage 可以假定 Express 实现是正确的。 我的handleRender如下所示

export function handleRender(req, res) {
  // Create a new Redux store instance
  const store = configureStore();

  const { dispatch } = store;

  dispatch(itemsFetchData(''http://5826ed963900d612000138bd.mockapi.io/items'')).then(() => {
    console.log("Y");
    // Render the component to a string
    const html = renderToString(
      <Provider store={store}>
        <div id="app">
          <StaticRouter context={{}} location={req.url}>
            <Main />
          </StaticRouter>
        </div>
      </Provider>
    );

    // Grab the initial state from our Redux store
    const preloadedState = store.getState();

    // Send the rendered page back to the client
    res.send(renderFullPage(html, preloadedState));
  });
}

使用上面的代码, Y被打印到控制台,但X永远不会被打印,这意味着没有调用 reducer 函数。 如果我从我的 handleRender 中的承诺中删除then ,从而变成:

dispatch(itemsFetchData(''http://5826ed963900d612000138bd.mockapi.io/items''));
console.log("Y");
// ... remaining code remains unaltered

reducer 函数被正确调用并且 Redux 存储正确更新,但是由于这是异步的, handleRender将已经返回 HTML。

任何帮助将不胜感激。 这是漫长的一天。

造成混乱的根源是因为在调用itemsFetchData之后注入了itemsFetchData 使用时,问题只是指出then ,因为没有它,成分Main其注入减速仍包括在内,似乎一切正常。 当它依托then我结束了与then无法调度,因为没有减速和Main部件不包括在内,因为它在等待调度。

为了解决这个问题,我在我的combineReducers包含了 reducer。

就像我说的,这是漫长的一天。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM