我正在尝试使用异步调用使服务器呈现工作。我的问题是,在渲染之前没有下载数据。
我的代码(也可在github:https://github.com/tomekbuszewski/server-rendering上找到)
server.js
require('babel-register');
import express from 'express';
import path from 'path';
import React from 'react';
import { renderToString } from 'react-dom/server';
import { Provider } from 'react-redux';
import { getState } from 'redux';
import { match, RouterContext } from 'react-router'
import routes from './app/routes';
import store from './app/store';
const app = express();
const port = 666;
app.get('/', (req, res) => {
match({ routes, location: req.url }, (error, redirectLocation, renderProps) => {
if (renderProps) {
console.log(renderProps.components);
res.send(renderToString(
<Provider store={store}>
<RouterContext {...renderProps} />
</Provider>
))
} else {
console.log('err')
}
});
});
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}`);
routes.js
import React from 'react';
import { Router, Route, browserHistory } from 'react-router';
import App from './Components/App';
const routes = (
<Router history={browserHistory}>
<Route path="/" component={App} />
</Router>
);
export default routes;
App组件具有提取功能:
const fetch = (dispatch) => {
const endpoint = '/data/index.json';
axios.get(endpoint).then((res) => {
Array.prototype.forEach.call(res.data, d => {
const payload = {
id: d.id,
title: d.title
};
dispatch({type: 'ADD_CONTENT', payload});
});
});
};
发送&#39; ADD_CONTENT&#39;动作:
case 'ADD_CONTENT':
return { ...state, data: [...state.data, action.payload] };
所有作品都很棒,客户端。
答案 0 :(得分:0)
例如:
const fetch = (dispatch) => {
const endpoint = '/data/index.json';
return axios.get(endpoint).then((res) => {
Array.prototype.forEach.call(res.data, d => {
const payload = {
id: d.id,
title: d.title
};
dispatch({type: 'ADD_CONTENT', payload});
});
});
};
在您的示例中,路由组件为App
在这种情况下,您将使用所需的redux操作来装饰该组件,该操作将预加载数据。
import { asyncConnect } from 'redux-connect';
@asyncConnect([{
promise: ({ store: { dispatch } }) => {
// `fetch` is your redux action returning a promise
return dispatch(fetch());
}
}])
@connect(
state => ({
// At this point, you can access your redux data as the
// fetch will have finished
data: state.myReducer.data
})
)
export default class App extends Component {
// ...the `data` prop here is preloaded even on the server
}
如果您不使用顶部容器中的数据,@connect
可以装饰嵌套组件,因为商店在应用范围内可用,但@asyncConnect
必须装饰直接调用的组件通过react-router
,它不能(到目前为止)在渲染树中的嵌套组件上使用,或者在初始渲染期间不会被解析
因为组件树的呈现仅在服务器上发生一次,所以组件本身无法调用该函数,需要在加载之前调用, via redux-connect
以及支持promises的redux操作,例如使用redux-thunk
中间件。