From 6e3dcf784b90750daa8bf3e3a58d282d58b05ea2 Mon Sep 17 00:00:00 2001 From: rodik Date: Fri, 15 Jan 2016 17:06:37 +0200 Subject: [PATCH 01/10] Migration to redux simple router and async-props --- package.json | 8 +- src/client.js | 17 ++- src/containers/App/App.js | 36 +++--- src/containers/Widgets/Widgets.js | 15 ++- src/helpers/Html.js | 9 +- src/helpers/__tests__/connectData-test.js | 29 ----- .../__tests__/getDataDependencies-test.js | 64 ---------- .../__tests__/getStatusFromRoutes-test.js | 52 --------- .../__tests__/makeRouteHooksSafe-test.js | 110 ------------------ src/helpers/asyncPropsResolver.js | 4 + src/helpers/connectData.js | 23 ---- src/helpers/getDataDependencies.js | 18 --- src/helpers/getStatusFromRoutes.js | 9 -- src/helpers/makeRouteHooksSafe.js | 43 ------- src/redux/create.js | 13 ++- src/redux/middleware/transitionMiddleware.js | 44 ------- src/redux/modules/reducer.js | 4 +- src/server.js | 45 +++---- 18 files changed, 74 insertions(+), 469 deletions(-) delete mode 100644 src/helpers/__tests__/connectData-test.js delete mode 100644 src/helpers/__tests__/getDataDependencies-test.js delete mode 100644 src/helpers/__tests__/getStatusFromRoutes-test.js delete mode 100644 src/helpers/__tests__/makeRouteHooksSafe-test.js create mode 100644 src/helpers/asyncPropsResolver.js delete mode 100644 src/helpers/connectData.js delete mode 100644 src/helpers/getDataDependencies.js delete mode 100644 src/helpers/getStatusFromRoutes.js delete mode 100644 src/helpers/makeRouteHooksSafe.js delete mode 100644 src/redux/middleware/transitionMiddleware.js diff --git a/package.json b/package.json index f2e49b008..111afacd0 100644 --- a/package.json +++ b/package.json @@ -82,13 +82,14 @@ } }, "dependencies": { + "async-props": "sars/async-props", "babel": "~5.8.29", "babel-plugin-typecheck": "^2.0.0", "body-parser": "^1.14.1", "compression": "^1.6.0", "express": "^4.13.3", "express-session": "^1.12.1", - "history": "1.17.0", + "history": "2.0.0-rc2", "file-loader": "^0.8.5", "http-proxy": "^1.12.0", "invariant": "^2.2.0", @@ -106,12 +107,11 @@ "react-helmet": "^2.2.0", "react-inline-css": "^2.0.0", "react-redux": "^4.0.0", - "react-router": "1.0.3", + "react-router": "2.0.0-rc5", "react-router-bootstrap": "^0.19.3", "redux": "^3.0.4", "redux-form": "^3.0.12", - "redux-router": "1.0.0-beta5", - "scroll-behavior": "^0.3.0", + "redux-simple-router": "^2.0.2", "serialize-javascript": "^1.1.2", "serve-favicon": "^2.3.0", "socket.io": "^1.3.7", diff --git a/src/client.js b/src/client.js index 948d9fc6f..0e17479a6 100644 --- a/src/client.js +++ b/src/client.js @@ -4,25 +4,20 @@ import 'babel/polyfill'; import React from 'react'; import ReactDOM from 'react-dom'; -import createHistory from 'history/lib/createBrowserHistory'; -import useScroll from 'scroll-behavior/lib/useStandardScroll'; import createStore from './redux/create'; import ApiClient from './helpers/ApiClient'; import io from 'socket.io-client'; import {Provider} from 'react-redux'; -import {reduxReactRouter, ReduxRouter} from 'redux-router'; +import { Router, browserHistory } from 'react-router'; +import AsyncProps from 'async-props'; +import asyncPropsResolver from './helpers/asyncPropsResolver'; import getRoutes from './routes'; -import makeRouteHooksSafe from './helpers/makeRouteHooksSafe'; const client = new ApiClient(); -// Three different types of scroll behavior available. -// Documented here: https://github.com/rackt/scroll-behavior -const scrollableHistory = useScroll(createHistory); - const dest = document.getElementById('content'); -const store = createStore(reduxReactRouter, makeRouteHooksSafe(getRoutes), scrollableHistory, client, window.__data); +const store = createStore(getRoutes, browserHistory, client, window.__data); function initSocket() { const socket = io('', {path: '/ws'}); @@ -40,7 +35,9 @@ function initSocket() { global.socket = initSocket(); const component = ( - + } history={browserHistory}> + {getRoutes(store)} + ); ReactDOM.render( diff --git a/src/containers/App/App.js b/src/containers/App/App.js index 5222ef2f7..bbdc31b37 100644 --- a/src/containers/App/App.js +++ b/src/containers/App/App.js @@ -9,25 +9,12 @@ import Helmet from 'react-helmet'; import { isLoaded as isInfoLoaded, load as loadInfo } from 'redux/modules/info'; import { isLoaded as isAuthLoaded, load as loadAuth, logout } from 'redux/modules/auth'; import { InfoBar } from 'components'; -import { pushState } from 'redux-router'; -import connectData from 'helpers/connectData'; +import { routeActions } from 'redux-simple-router'; import config from '../../config'; -function fetchData(getState, dispatch) { - const promises = []; - if (!isInfoLoaded(getState())) { - promises.push(dispatch(loadInfo())); - } - if (!isAuthLoaded(getState())) { - promises.push(dispatch(loadAuth())); - } - return Promise.all(promises); -} - -@connectData(fetchData) @connect( state => ({user: state.auth.user}), - {logout, pushState}) + {logout, pushState: routeActions.push}) export default class App extends Component { static propTypes = { children: PropTypes.object.isRequired, @@ -43,17 +30,30 @@ export default class App extends Component { componentWillReceiveProps(nextProps) { if (!this.props.user && nextProps.user) { // login - this.props.pushState(null, '/loginSuccess'); + this.props.pushState('/loginSuccess'); } else if (this.props.user && !nextProps.user) { // logout - this.props.pushState(null, '/'); + this.props.pushState('/'); } } + static loadProps(params) { + const {dispatch, getState} = params.store; + const promises = []; + + if (!isInfoLoaded(getState())) { + promises.push(dispatch(loadInfo())); + } + if (!isAuthLoaded(getState())) { + promises.push(dispatch(loadAuth())); + } + return Promise.all(promises); + } + handleLogout = (event) => { event.preventDefault(); this.props.logout(); - } + }; render() { const {user} = this.props; diff --git a/src/containers/Widgets/Widgets.js b/src/containers/Widgets/Widgets.js index 001e3a758..77284931b 100644 --- a/src/containers/Widgets/Widgets.js +++ b/src/containers/Widgets/Widgets.js @@ -4,16 +4,8 @@ import {connect} from 'react-redux'; import * as widgetActions from 'redux/modules/widgets'; import {isLoaded, load as loadWidgets} from 'redux/modules/widgets'; import {initializeWithKey} from 'redux-form'; -import connectData from 'helpers/connectData'; import { WidgetForm } from 'components'; -function fetchDataDeferred(getState, dispatch) { - if (!isLoaded(getState())) { - return dispatch(loadWidgets()); - } -} - -@connectData(null, fetchDataDeferred) @connect( state => ({ widgets: state.widgets.data, @@ -31,6 +23,13 @@ export default class Widgets extends Component { editing: PropTypes.object.isRequired, load: PropTypes.func.isRequired, editStart: PropTypes.func.isRequired + }; + + static loadProps(params) { + const {dispatch, getState} = params.store; + if (!isLoaded(getState())) { + return dispatch(loadWidgets()); + } } render() { diff --git a/src/helpers/Html.js b/src/helpers/Html.js index 9e415a994..3f694eeaa 100644 --- a/src/helpers/Html.js +++ b/src/helpers/Html.js @@ -16,11 +16,12 @@ export default class Html extends Component { static propTypes = { assets: PropTypes.object, component: PropTypes.node, - store: PropTypes.object - } + store: PropTypes.object, + asyncProps: PropTypes.object + }; render() { - const {assets, component, store} = this.props; + const {assets, component, store, asyncProps} = this.props; const content = component ? ReactDOM.renderToString(component) : ''; const head = Helmet.rewind(); @@ -49,6 +50,8 @@ export default class Html extends Component {
+ {asyncProps &&