Javascript 仅在初始页面加载时使用服务器端呈现
我想使用react的服务器端渲染只获取用户的初始状态。之后,我更喜欢使用websockets/ajax/客户端路由来处理应用程序 这就是我目前所拥有的Javascript 仅在初始页面加载时使用服务器端呈现,javascript,reactjs,react-router,Javascript,Reactjs,React Router,我想使用react的服务器端渲染只获取用户的初始状态。之后,我更喜欢使用websockets/ajax/客户端路由来处理应用程序 这就是我目前所拥有的 function handleRender(req,res){ getInitialState(id_token) .then(function(initialState){ const store = createStore(rootReducer,initialState) consol
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>`
}
功能手柄控制器(要求,res){
getInitialState(id\u令牌)
.then(函数(初始状态){
const store=createStore(rootReducer,initialState)
console.log('store.getState()',store.getState())
常量html=renderToString(
)
res.send(renderFullPage(html,initialState))
})
.catch(函数(err){
console.log('错误')
})
}
const renderFullPage=(html,initialState)=>{
返回`
Redux通用
${html}
window.\uuuu INITIAL\u STATE\uuuu=${JSON.stringify(initialState)}
`
}
我的客户端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')
)
const initialState=window.\uu初始状态__
export const store=createStore(rootReducer,initialState)
ReactDOM.render(
,document.getElementById('app')
)
上述方法效果良好。当我在客户端导航到/project时。项目组件将渲染
但是,当我在/project刷新页面时,我会在客户端路由器移动到/project之前快速呈现/page
此外,每当我在路由之间切换时,我都会再次点击服务器,这是我不想要的 我知道这应该发生,因为刷新再次命中服务器,导致服务器发回
<Provider store={store}>
<App/>
</Provider>
这将渲染应用程序组件,然后react router将再次渲染/项目组件
是否有一种方法可以直接从服务器获取窗口、\uuuu初始状态和初始HTML,而不必在每次刷新/路由更改时发送HTML
我不想在每一次路线改变时都攻击服务器,我相信这就是universal的反应
对我来说,最重要的是获取页面加载时用户的初始状态。我更喜欢将应用程序作为spa(仅针对初始渲染/状态和api请求点击服务器)我很确定您缺少将服务器端请求的路由与react路由器中的路由相匹配的部分
从'react router'导入{RoutingContext,match};
从“history/lib/createLocation”导入createLocation;
从“/react routes”导入路由;
app.get(“/*”,(请求、恢复、下一步)=>{
//从请求的url创建“位置”对象
const location=createLocation(请求url);
//将位置与我们的反应路线相匹配
匹配({routes,location},(err,redirect,renderProps)=>{
如果(错误){
控制台错误(err);
返回res.status(500.end)(“内部服务器错误”);
}
如果(!renderProps)返回res.status(404.end('notfound');
getInitialState(id_令牌)。然后((initialState)=>{
const store=createStore(rootReducer,initialState);
常量html=renderToString(
{() =>
}
);
res.send(renderFullPage(html,initialState));
});
});
});
退房。并非所有内容都适用于您的情况,但请查看和。handleRender在哪里被呼叫?“此外,每当我在路由之间切换时,我都会再次点击服务器,这是我不想要的。”。请为我澄清这一点。SPA与react路由器及其链接不会导致窗口刷新,也不会“在每次路由更改时命中服务器”@idbehold-handlerender被设置为快速中间件-app.use(handlerender)
@Yozi-路由更改因某种原因命中服务器:(…你认为这可能是因为我没有呈现路由器上下文和初始状态吗?@Kunkka,我认为这可能是一个严重的错误或类似的错误,请在控制台中检查。你的客户端呈现看起来正确,我的关于相同,这基本上意味着我在每个url请求上都会命中服务器?即使是对于/项目?@Kunkka so long当您使用
元素在站点周围导航时,则不会。
元素将使用您的react路由器更改页面上的内容。除非您显式刷新页面或在新选项卡中打开链接,否则它不会加载整页。@Kunkka例如,如果您打开一个新选项卡,然后输入yoursite.com/foo然后您的服务器将生成并发送该页面的HTML。如果您随后单击转到/bar的
,则您将看到地址栏更新以反映该导航,但是您不会进行完整页面加载。监控您的网络流量,您将看到没有向yoursite.com/bar发出请求。