我是服务器端渲染的新手。我正在尝试像下面那样实现它,但是显示错误。
index.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<div id="root"></div>
</body>
</html>
index.js
import React from 'react';
import ReactDOM from 'react-dom'
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk'
import { Provider } from 'react-redux'
import rootReducer from './reducers'
import './index.css'
import Main from './Main'
const preloadedState = window.__PRELOADED_STATE__
delete window.__PRELOADED_STATE__
const store = createStore(
rootReducer,
preloadedState,
applyMiddleware(thunk)
);
ReactDOM.hydrate(
<Provider store={store}>
<Main />
</Provider>,
document.getElementById('root')
);
server.js
import express from 'express';
import open from 'open';
import rootReducer from '../src/reducers'
import Main from '../src/Main';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import { renderToString } from 'react-dom/server'
var app = express();
const port = 4000;
app.use(express.static('dist'));
app.get('/', (req, res) => {
const store = createStore(rootReducer)
const html = renderToString(
<Provider store={store}>
<Main />
</Provider>
)
const preloadedState = store.getState();
res.send(renderFullPage(html, preloadedState))
});
function renderFullPage(html, preloadedState) {
return `
<!doctype html>
<html>
<body>
<div id="root">${html}</div>
<script>
window.__PRELOADED_STATE__ = ${JSON.stringify(preloadedState).replace(/</g,'\\u003c')}
</script>
</body>
</html>
`
}
app.listen(port, function (err) {
if (err) {
console.log(err);
} else {
open('http://localhost:' + port);
}
})
当我尝试运行SSR时,显示以下错误。我不明白我在做什么错?
Warning: Expected server HTML to contain a matching <div> in <div>.
任何帮助将不胜感激。
编辑:
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Content from './components/Content';
import PageNotFound from './components/PageNotFound'
import Movie from './components/Movie';
class Main extends Component {
render() {
return (
<div className="main">
<Router>
<Switch>
<Route exact path='/' component={Content} />
<Route path='/search/:query' component={Content} />
<Route path='/film/:id' component={Movie} />
<Route path='*' component={PageNotFound} />
</Switch>
</Router>
</div>
);
}
}
export default Main;
这不是给定链接的重复,因为我正在使用SSR。那么为什么我应该像使用SSR一样使用渲染而不是水合呢?