5

假设我有一个如下所示的组件。

User extends React.Component {
  componentDidMount() {
    this.props.fetchUserDetails(this.props.params.userSlugName);
    // this slug name is coming from route params (ex: path is /users/:userSlugName)
  }
  // Other lifecycle methods
}

User.loadData = () => {
  // some data fetching logic for backend
}

我正在使用带有 react-router-config 设置的 react-router v4。我的想法不多了。如何在服务器中获取 userSlugName。

现在如何在服务器中预取这些详细信息以使 SSR 正常工作。

4

1 回答 1

0

在服务器端渲染中加入异步逻辑有点棘手。当您调用 renderToString() 时,您将获得初始 render() 的 html。您需要的是数据进入时发生的后续 render() 的 html。

基本思想如下:

  • 执行 API 调用
  • 等他们说完
  • 返回最终渲染的 html()

您可以尝试 Redux 网站 ( https://redux.js.org/recipes/server-rendering#async-state-fetching ) 或本教程 ( https://www.sitepoint.com/asynchronous-apis ) 上提到的方法-服务器渲染反应/)。

我更喜欢后者,它更通用,您不需要为每个组件使用不同的获取代码。不过,您可能需要调整代码以使其更简单。有关反应路由器上下文 API 的更多详细信息:https ://medium.freecodecamp.org/how-to-protect-your-routes-with-react-context-717670c4713a

function handleRender(req, res) {
    const fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;
    console.log('fullUrl: ', fullUrl);
    console.log('req.url: ', req.url);

    // Create a new Redux store instance
    const store = createStore(reducerFn);
    const context = {};    // Store stuff here

    const urlToRender = req.url;
    // Render the component to a string
    const html1 = renderToString(
        <Provider store={store}>
            <StaticRouter location={urlToRender} context={context}>
                {routes}
            </StaticRouter>
        </Provider>
    );

    // Get promises from context, wait for all of them to finish
    // Render again
    const html = renderToString(
        <Provider store={store}>
            <StaticRouter location={urlToRender} context={context}>
                {routes}
            </StaticRouter>
        </Provider>
    );
    const helmet = Helmet.renderStatic();

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

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

有机会我会分享https://www.heloprotocol.in/的代码。

于 2019-02-15T18:26:52.720 回答