react + redux + saga +服务器端渲染+如何停止服务器端渲染页面的额外ajax调用?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了react + redux + saga +服务器端渲染+如何停止服务器端渲染页面的额外ajax调用?相关的知识,希望对你有一定的参考价值。
我正在开展一个网络项目。在这个项目中,我们使用服务器端渲染与节点,表达和反应。为了获取数据和Redux,我们使用Redux-Saga。只有一个问题。每个页面都是从服务器呈现的,当我们到达浏览器时,我们的应用程序就像一个客户端应用程序。如果页面有一些ajax调用,并且该页面从服务器呈现,虽然它具有服务器所需的所有数据,但在客户端它会进行ajax调用。我想停止额外的ajax调用。我想从服务器跳过所请求页面的ajax调用。
这是客户端的index.jsx文件。
import App from './App'
import ReactDOM from 'react-dom'
import React from 'react';
import { Provider } from 'react-redux';
import { ConnectedRouter } from 'react-router-redux'
import getStore from './getStore';
import createHistory from 'history/createBrowserHistory';
import './styles/styles.scss';
const history = createHistory();
const store = getStore(history);
if (module.hot) {
module.hot.accept('./App', () => {
const NextApp = require('./App').default;
render(NextApp);
});
}
const render = (_App) => {
ReactDOM.render(
<Provider store={store}>
<ConnectedRouter history={history}>
<_App />
</ConnectedRouter>
</Provider>
, document.getElementById("AppContainer"));
};
store.subscribe(() => {
const state = store.getState();
if (state.items.length > 0) {
render(App);
}
});
const fetchDataForLocation = location => {
if (location.pathname === "/") {
store.dispatch({ type: `REQUEST_FETCH_ITEMS` });
}
};
fetchDataForLocation(history.location);
history.listen(fetchDataForLocation);
这是服务器的index.js文件
import path from 'path';
import express from 'express';
import webpack from 'webpack';
import yields from 'express-yields';
import fs from 'fs-extra';
import App from '../src/App';
import { renderToString } from 'react-dom/server';
import React from 'react'
import { argv } from 'optimist';
import { ConnectedRouter } from 'react-router-redux';
import getStore from '../src/getStore'
import { Provider } from 'react-redux';
import createHistory from 'history/createMemoryHistory';
import open from 'open';
import { get } from 'request-promise';
const port = process.env.PORT || 4000;
const app = express();
const useServerRender = argv.useServerRender === 'true';
const inDebugMode = argv.inDebugMode == 'true';
let indexPath = inDebugMode ? '../public/index.html' : './public/index.html';
let mediaPath = inDebugMode ? '../src/styles/media' : './src/styles/media';
app.use('/media', express.static(mediaPath));
function* getItems() {
let data = yield get("http://localhost:3826/api/item/getall", { gzip: true });
return JSON.parse(data);
}
if (process.env.NODE_ENV === 'development') {
const config = require('../webpack.config.dev.babel.js').default;
const compiler = webpack(config);
app.use(require('webpack-dev-middleware')(compiler, {
noInfo: true,
stats: {
assets: false,
colors: true,
version: false,
hash: false,
timings: false,
chunks: false,
chunkModules: false
}
}));
app.use(require('webpack-hot-middleware')(compiler));
} else {
app.use(express.static(path.resolve(__dirname, '../dist')));
}
app.get(['/', '/aboutus'], function* (req, res) {
let index = yield fs.readFile(indexPath, "utf-8");
const initialState = {
items: []
};
if (req.path == '/') {
const items = yield getItems();
initialState.items = items.data.items;
}
const history = createHistory({
initialEntries: [req.path]
});
const store = getStore(history, initialState);
if (useServerRender) {
const appRendered = renderToString(
<Provider store={store}>
<ConnectedRouter history={history}>
<App />
</ConnectedRouter>
</Provider>
);
index = index.replace(`<%= preloadedApplication %>`, appRendered)
} else {
index = index.replace(`<%= preloadedApplication %>`, `Please wait while we load the application.`);
}
res.send(index);
});
app.listen(port, '0.0.0.0', () => {
console.info(`Listening at http://localhost:${port}`);
if (process.env.NODE_ENV === 'development') {
open(`http://localhost:${port}`);
}
});
我想如果我们能够以某种方式在客户端使用服务器端存储,我们可能会克服这个问题。
答案
这都是关于商店数据的。我们应该以某种方式将商店数据发送到客户端,并将这些数据用于客户端的存储。
对我来说,最好的解决方案是通过HTML:
<script id='app-props' type='application/json'>
<![CDATA[<%= initialData %>]]>
</script>
在商店文件中我检索它像这样:
if (typeof window !== 'undefined') {
let initialDataEl = document.getElementById('app-props');
try {
let props = initialDataEl.textContent;
props = props.replace("<![CDATA[", "").replace("]]>", "");
defaultState = JSON.parse(props);
}
catch (err) {
console.log(err);
}
}
以上是关于react + redux + saga +服务器端渲染+如何停止服务器端渲染页面的额外ajax调用?的主要内容,如果未能解决你的问题,请参考以下文章