I have a fork of Redux saga boilerplate and I try to update store on the server side by action. It goes well, but the component does not update (don't call mapStateToProps) when the store was updated. What's wrong? Help, please.
Component source:
import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { testAction } from '../../actions';
class Event extends Component {
static propTypes = {
title: PropTypes.string,
testAction: PropTypes.func
}
componentWillMount() {
this.props.testAction({ test: 'test' });
}
render() {
return (
<div>
Event - {this.props.title}
</div>
);
}
}
function mapStateToProps(state) {
console.log(state);
return {
title: state.default.test
};
}
export default connect(
mapStateToProps,
{ testAction }
)(Event);
server.js source:
import Express from 'express';
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import favicon from 'serve-favicon';
import compression from 'compression';
import http from 'http';
import proxy from 'express-http-proxy';
import path from 'path';
import url from 'url';
import { match, createMemoryHistory } from 'react-router';
import config from './config';
import configureStore from './store/configureStore';
import Html from './helpers/Html';
import getRoutes from './routes';
import waitAll from './sagas/waitAll';
import { Root } from 'containers';
const app = new Express();
const server = new http.Server(app);
// disable `X-Powered-By` HTTP header
app.disable('x-powered-by');
app.use(compression());
app.use(favicon(path.join(__dirname, '..', 'static', 'favicon.ico')));
app.use(Express.static(path.join(__dirname, '..', 'static')));
// Proxy to API
app.use('/api', proxy(config.apiBaseUrl, {
// eslint-disable-next-line
forwardPath: (req, res) => url.parse(req.url).path
}));
app.use((req, res) => {
if (__DEVELOPMENT__) {
webpackIsomorphicTools.refresh();
}
const memoryHistory = createMemoryHistory();
const store = configureStore();
const allRoutes = getRoutes(store);
const assets = webpackIsomorphicTools.assets();
function hydrateOnClient() {
const htmlComponent = <Html assets={assets} store={store} />;
const renderedDomString = ReactDOMServer.renderToString(htmlComponent);
res.send(`<!doctype html>\n ${renderedDomString}`);
}
if (__DISABLE_SSR__) {
hydrateOnClient();
return;
}
match({ routes: allRoutes, location: req.url }, (error, redirectLocation, renderProps) => {
if (redirectLocation) {
res.redirect(redirectLocation.pathname + redirectLocation.search);
} else if (error) {
console.error('ROUTER ERROR:', error);
res.status(500);
hydrateOnClient();
} else if (renderProps) {
const preloaders = renderProps.components
.filter((component) => component && component.preload)
.map((component) => component.preload(renderProps.params, req))
.reduce((result, preloader) => result.concat(preloader), []);
const runTasks = store.runSaga(waitAll(preloaders));
runTasks.done.then(() => {
const rootComponent = (<Root
store={store}
routes={allRoutes}
history={memoryHistory}
renderProps={renderProps}
type="server"
/>);
const htmlComponent = <Html assets={assets} component={rootComponent} store={store} />;
const renderedDomString = ReactDOMServer.renderToString(htmlComponent);
global.navigator = { userAgent: req.headers['user-agent'] };
res.status(200).send(`<!doctype html>\n ${renderedDomString}`);
}).catch((e) => {
console.log(e.stack);
});
store.close();
} else {
res.status(404).send('Not found');
}
});
});
if (config.port) {
server.listen(config.port, (err) => {
if (err) {
console.error(err);
}
console.info('==> Open http://%s:%s in a browser to view the app.', config.host, config.port);
});
} else {
console.error('==> ERROR: No PORT environment variable has been specified');
}