我正在学习如何在服务器上渲染我的React站点。到目前为止,我已经设法使用异步数据进行渲染,但是当我包含脚本时我遇到了问题(当我想要同构应用程序时,我会遇到问题):
Warning: React attempted to reuse markup in a container but the checksum was invalid (...):
(client) <!-- react-empty: 1 -
(server) <div class="blah" dat
我无法弄清楚为什么会这样。我的代码如下:
服务器
require('babel-register');
import express from 'express';
import path from 'path';
import React from 'react';
import { renderToString } from 'react-dom/server'
import { match } from 'react-router'
import { ReduxAsyncConnect, loadOnServer, reducer as reduxAsyncConnect } from 'redux-connect'
import { Provider } from 'react-redux';
import routes from './app/routes';
import store from './app/store';
const app = express();
const port = 3100;
const createPage = (html) => {
return `<!doctype html>
<html>
<head>
<title>123</title>
</head>
<body>
<div id="app">${html}</div>
<script src="/public/index.js"></script>
</body>
</html>`
};
app.get('/', (req, res) => {
match({ routes, location: req.url }, (err, redirect, renderProps) => {
loadOnServer({ ...renderProps, store }).then(() => {
const appHTML = renderToString(
<Provider store={store} key="provider">
<ReduxAsyncConnect {...renderProps} />
</Provider>
);
const html = createPage(appHTML);
res.send(html);
}).catch((e) => { console.log(e); })
})
});
app.use('/public', express.static(path.join(__dirname, 'public')));
app.use('/data', express.static(path.join(__dirname, 'data')));
app.listen(port);
console.log(`localhost:${port}`);
路线:
import React from 'react';
import { Router, Route, browserHistory } from 'react-router';
import { ReduxAsyncConnect, asyncConnect, reducer as reduxAsyncConnect } from 'redux-connect'
import App from './Components/App';
import { Provider } from 'react-redux';
import store from './store';
const routes = (
<Provider store={store} key="provider">
<Router render={(props) => <ReduxAsyncConnect {...props} />} history={browserHistory}>
<Route path="/" component={App}/>
</Router>
</Provider>
);
export default routes;
主要(客户)
import React from 'react';
import { render } from 'react-dom';
import routes from './routes';
import { match } from 'react-router'
match({ routes, location: '/' }, () => {
render(routes, document.getElementById('app'))
});
我确定某个地方有一个小错误会产生这个错误,但我似乎无法找到它。
答案 0 :(得分:1)
I guess the client side is missing the state to render the app correctly. You need to pass down the app state to the client. This is also called rehydration.
You can do this by serializing your state on the server and sending it down as a JSON string with the rendered html. On the client side you can parse the serialized state and use it as an initial state when creating the store
. This will result in both renders, the server and the first client side one, to produce the same markup --> the checksum equals.
Check the second argument you can pass to createStore
http://redux.js.org/docs/api/createStore.html