且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

异步路由导致服务器端校验和无效错误

更新时间:2022-12-25 13:24:24

我得到的原因是 您正在尝试使用服务器渲染将组件渲染到文档,但校验和无效.这通常意味着您在客户端上渲染了与服务器上不同的组件类型或道具,或者您的 render() 方法不纯.

并通过在客户端上使用 match 修复它,如下所述:https://github.com/reactjs/react-router/blob/master/docs/guides/ServerRendering.md#async-routes>

文档建议:

match({ history, routes }, (error, redirectLocation, renderProps) => {render(<Router {...renderProps}/>, mountNode)})

对我有用的特定非 JSX 客户端代码(将稍微重构一下):

var match = ReactRouter.match;var Router = React.createFactory(ReactRouter.Router);var Provider = React.createFactory(ReactRedux.Provider)匹配({历史:appHistory,路线:路线},功能(错误,redirectLocation,renderProps){ReactDOM.render(提供者({商店:商店},路由器(renderProps)),$(文件)[0]);});

I'm using Webpack, react, react-router, react-redux, redux, and simple-redux-router.

I got this error while using react-router with async routes and server-side rendering:

bundle.js:1 Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:

(client) <noscript data-reacti
(server) <div data-reactid=".1

My routes.cjsx has this:

# Routes
path: 'game'
getComponent: (location, cb) =>
    require.ensure [], (require) =>
        cb null, require './views/game'

If I change it to this, I no longer get that error:

# Routes
path: 'game'
getComponent: (location, cb) =>
    cb null, require './views/game'

Is there a better way to deal with this issue when using async routes?

I got this as You're trying to render a component to the document using server rendering but the checksum was invalid. This usually means you rendered a different component type or props on the client from the one on the server, or your render() methods are impure.

And fixed it by using match on the client, as described here: https://github.com/reactjs/react-router/blob/master/docs/guides/ServerRendering.md#async-routes

The doc suggests:

match({ history, routes }, (error, redirectLocation, renderProps) => {
  render(<Router {...renderProps} />, mountNode)
})

Specific non-JSX client-side code that works for me (will refactor a bit):

var match = ReactRouter.match;
var Router = React.createFactory(ReactRouter.Router);
var Provider = React.createFactory(ReactRedux.Provider)
match({ history: appHistory, routes: routes }, function (error, redirectLocation, renderProps) {
  ReactDOM.render(
      Provider({store: store},
      Router(renderProps)),
        $(document)[0]
  );
});