我想使用react的服务器端渲染来仅获取用户的初始状态。之后,我更喜欢使用 websockets/ajax/客户端路由来处理应用程序。
这就是我目前所拥有的
function handleRender(req,res){
getInitialState(id_token)
.then(function(initialState){
const store = createStore(rootReducer,initialState)
console.log('store.getState() ',store.getState())
const html = renderToString(
<Provider store={store}>
<App/>
</Provider>
)
res.send(renderFullPage(html,initialState))
})
.catch(function(err){
console.log('error')
})
}
const renderFullPage = (html,initialState) => {
return `
<!doctype html>
<html>
<head>
<title>Redux Universal</title>
</head>
<body>
<div id="app"><div>${html}</div></div>
<script>
window.__INITIAL_STATE__= ${JSON.stringify(initialState)}
</script>
<script src="/bundle.js"></script>
</body>
</html>`
}
我的客户端index.js 几乎是标准的
const initialState = window.__INITIAL_STATE__
export const store = createStore(rootReducer,initialState)
ReactDOM.render(
<Provider store={store}>
<Router history={browserHistory}>
<Route path="/" component={App} />
<Route path ="/project" component={Project} />
</Router>
</Provider>
,document.getElementById('app')
)
以上效果很好。当我导航到客户端的/project 时。项目组件呈现。
但是,当我在/project 刷新页面时 - 在客户端路由器移动到/project 之前,我会快速渲染/页面。
此外,每当我在路线之间切换时,我都会再次访问服务器,这是我不想要的。
我知道这应该发生,因为刷新再次命中服务器导致它发回
<Provider store={store}>
<App/>
</Provider>
渲染应用程序组件,然后react-router再次渲染/project组件。
有没有一种方法可以让我从服务器获取window.__INITIAL_STATE__
和初始HTML,而不必在每次刷新/路由更改时发送html。
我不想在每次路由更改时都访问服务器,这就是我所相信的通用 react 。
对我来说最重要的是获取用户在页面加载时的初始状态。我更喜欢将应用程序作为水疗中心(仅针对初始渲染/状态和 API 请求访问服务器)
最佳答案
我很确定您错过了将服务器端请求的路由与 react 路由器中的路由相匹配的部分。
import { RoutingContext, match } from 'react-router';
import createLocation from 'history/lib/createLocation';
import routes from './react-routes';
app.get('/*', (req, res, next) => {
// create a "location" object from the requested url
const location = createLocation(req.url);
// match the location to the react routes we have
match({ routes, location }, (err, redirect, renderProps) => {
if (err) {
console.error(err);
return res.status(500).end('Internal server error');
}
if (!renderProps) return res.status(404).end('Not found');
getInitialState(id_token).then((initialState) => {
const store = createStore(rootReducer,initialState);
const html = renderToString(
<Provider store={store}>
{() =>
<RoutingContext {...renderProps} />
}
</Provider>
);
res.send(renderFullPage(html,initialState));
});
});
});
查看this isomorphic redux example app 。并非所有内容都适用于您的情况,但请查看 server.js , client.js ,和routes.js .
关于javascript - 仅将服务器端渲染用于初始页面加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38269595/