Skip to content

Commit

Permalink
Merge pull request #787 from langpavel/react-intl-merge-redux
Browse files Browse the repository at this point in the history
[feature/react-intl] merge feature/redux
  • Loading branch information
langpavel authored Aug 2, 2016
2 parents 031c510 + 1dd8893 commit bbc2f08
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 26 deletions.
9 changes: 9 additions & 0 deletions src/actions/route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

// Pseudo action. All is handled through history module
export function redirect(descriptor) {
return (dispatch, _, { history }) => history.replace(descriptor);
}

export function navigate(descriptor) {
return (dispatch, _, { history }) => history.push(descriptor);
}
6 changes: 4 additions & 2 deletions src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import ReactDOM from 'react-dom';
import FastClick from 'fastclick';
import UniversalRouter from 'universal-router';
import routes from './routes';
import history from './core/history';
import createHistory from './core/createHistory';
import configureStore from './store/configureStore';
import { readState, saveState } from 'history/lib/DOMStateStorage';
import {
Expand Down Expand Up @@ -108,6 +108,7 @@ function render(container, state, config, component) {
}

export default function main() {
const history = createHistory();
const container = document.getElementById('app');
const initialState = JSON.parse(
document.
Expand All @@ -119,8 +120,9 @@ export default function main() {
// Make taps on links and buttons work fast on mobiles
FastClick.attach(document.body);

const store = configureStore(initialState, {});
const store = configureStore(initialState, { history });
context.store = store;
context.createHref = history.createHref;

// Re-render the app when window.location changes
function onLocationChange(location) {
Expand Down
4 changes: 4 additions & 0 deletions src/components/App/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class App extends Component {

static propTypes = {
context: PropTypes.shape({
createHref: PropTypes.func.isRequired,
store: PropTypes.object.isRequired,
insertCss: PropTypes.func,
setTitle: PropTypes.func,
setMeta: PropTypes.func,
Expand All @@ -27,6 +29,7 @@ class App extends Component {
};

static childContextTypes = {
createHref: PropTypes.func.isRequired,
insertCss: PropTypes.func.isRequired,
setTitle: PropTypes.func.isRequired,
setMeta: PropTypes.func.isRequired,
Expand All @@ -35,6 +38,7 @@ class App extends Component {
getChildContext() {
const context = this.props.context;
return {
createHref: context.createHref,
insertCss: context.insertCss || emptyFunction,
setTitle: context.setTitle || emptyFunction,
setMeta: context.setMeta || emptyFunction,
Expand Down
24 changes: 19 additions & 5 deletions src/components/Link/Link.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
*/

import React, { Component, PropTypes } from 'react';
import history from '../../core/history';
import { connect } from 'react-redux';
import { navigate } from '../../actions/route';

function isLeftClickEvent(event) {
return event.button === 0;
Expand All @@ -23,6 +24,13 @@ class Link extends Component { // eslint-disable-line react/prefer-stateless-fun
static propTypes = {
to: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired,
onClick: PropTypes.func,

// actions
navigate: PropTypes.func,
};

static contextTypes = {
createHref: PropTypes.func.isRequired,
};

handleClick = (event) => {
Expand All @@ -44,9 +52,9 @@ class Link extends Component { // eslint-disable-line react/prefer-stateless-fun

if (allowTransition) {
if (this.props.to) {
history.push(this.props.to);
this.props.navigate(this.props.to);
} else {
history.push({
this.props.navigate({
pathname: event.currentTarget.pathname,
search: event.currentTarget.search,
});
Expand All @@ -56,9 +64,15 @@ class Link extends Component { // eslint-disable-line react/prefer-stateless-fun

render() {
const { to, ...props } = this.props; // eslint-disable-line no-use-before-define
return <a href={history.createHref(to)} {...props} onClick={this.handleClick} />;
return <a href={this.context.createHref(to)} {...props} onClick={this.handleClick} />;
}

}

export default Link;
const mapState = null;

const mapDispatch = {
navigate,
};

export default connect(mapState, mapDispatch)(Link);
4 changes: 1 addition & 3 deletions src/core/history.js → src/core/createHistory.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,4 @@ import createHistory from 'history/lib/createBrowserHistory';
import createMemoryHistory from 'history/lib/createMemoryHistory';
import useQueries from 'history/lib/useQueries';

const history = useQueries(process.env.BROWSER ? createHistory : createMemoryHistory)();

export default history;
export default useQueries(process.env.BROWSER ? createHistory : createMemoryHistory);
55 changes: 39 additions & 16 deletions src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import passport from './core/passport';
import models from './data/models';
import schema from './data/schema';
import routes from './routes';
import createHistory from './core/createHistory';
import assets from './assets'; // eslint-disable-line import/no-unresolved
import configureStore from './store/configureStore';
import { setRuntimeVariable } from './actions/runtime';
Expand Down Expand Up @@ -101,21 +102,39 @@ app.use('/graphql', expressGraphQL(req => ({
// Register server-side rendering middleware
// -----------------------------------------------------------------------------
app.get('*', async (req, res, next) => {
try {
let css = [];
let statusCode = 200;
const locale = req.language;
const data = {
lang: locale,
title: '',
description: '',
style: '',
script: assets.main.js,
children: '',
};
let css = [];
let statusCode = 200;
const locale = req.language;
const data = {
lang: locale,
title: '',
description: '',
style: '',
script: assets.main.js,
children: '',
};

const history = createHistory(req.url);
// let currentLocation = history.getCurrentLocation();
let sent = false;
const removeHistoryListener = history.listen(location => {
const newUrl = `${location.pathname}${location.search}`;
if (req.originalUrl !== newUrl) {
// console.log(`R ${req.originalUrl} -> ${newUrl}`); // eslint-disable-line no-console
if (!sent) {
res.redirect(303, newUrl);
sent = true;
next();
} else {
console.error(`${req.path}: Already sent!`); // eslint-disable-line no-console
}
}
});

try {
const store = configureStore({}, {
cookie: req.headers.cookie,
history,
});

store.dispatch(setRuntimeVariable({
Expand All @@ -137,6 +156,7 @@ app.get('*', async (req, res, next) => {
query: req.query,
context: {
store,
createHref: history.createHref,
insertCss: (...styles) => {
styles.forEach(style => css.push(style._getCss())); // eslint-disable-line no-underscore-dangle, max-len
},
Expand Down Expand Up @@ -166,12 +186,15 @@ app.get('*', async (req, res, next) => {
},
});

const html = ReactDOM.renderToStaticMarkup(<Html {...data} />);

res.status(statusCode);
res.send(`<!doctype html>${html}`);
if (!sent) {
const html = ReactDOM.renderToStaticMarkup(<Html {...data} />);
res.status(statusCode);
res.send(`<!doctype html>${html}`);
}
} catch (err) {
next(err);
} finally {
removeHistoryListener();
}
});

Expand Down
1 change: 1 addition & 0 deletions src/store/createHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,6 @@ export default function createHelpers(config) {
return {
fetch: fetchKnowingCookie,
graphqlRequest,
history: config.history,
};
}

0 comments on commit bbc2f08

Please sign in to comment.