Skip to content

Commit

Permalink
Implement React Router@4.0.0 (#393)
Browse files Browse the repository at this point in the history
* removed react-router form package.json & installed react-router-dom.

* completed index.src refactor.

* re-implemented App.js

* added notes to import changes & App.js

* modified middleware array @ store/configureStore.js

* updated yarn.lock file with fresh `yarn` command.

* updated master branch.

* upgraded react-hot-reloader to @3.0.0-beta.6

* removed extra "document.getElementById(app) from Root.js

* moved react-router-redux to regular "dependencies" from "dev-dependencies"

* cleaned Root.propTypes.

* cleaned Root.js & App.js per @oshalygin feedback.

* replaced .gitignore comment.

* removed react-router form package.json & installed react-router-dom.

* completed index.src refactor.

* re-implemented App.js

* added notes to import changes & App.js

* Update FAQ.md

fixed header on FAQ page

* Update README.md

fixed a few headers improperly declared

* modified middleware array @ store/configureStore.js

* Add react hot loader 3 (#392)

- This commit wires up react-hot-loader 3 to
  be used in the application.  There are numerous
  benefits to the latest release, all of which
  can be seen at https://github.com/gaearon/react-hot-loader
- Note that the specific implementation around
  wrapping in a Root component is part of how
  react-hot-loader 3 needs to be configured.
- Note that the package is brought in as a
  dependency, not a dev dependency because of
  how it is switched at runtime or not.
- More information on the migration can be
  viewed at:
https://github.com/gaearon/react-hot-loader/tree/master/docs\#migration-to-30

Related: #216

* Updated react-hot-loader to correct package version. (#401)

* Add item to check if issues

* updated yarn.lock file with fresh `yarn` command.

* Fix formatting (#403)

* updated master branch.

* upgraded react-hot-reloader to @3.0.0-beta.6

* removed extra "document.getElementById(app) from Root.js

* moved react-router-redux to regular "dependencies" from "dev-dependencies"

* cleaned Root.js & App.js per @oshalygin feedback.

* replaced .gitignore comment.

* clean index.js

* Add CONTRIBUTE.md (#431)

* Add

* Updated yarn lock using upgrade

* Rename

* Update

* Upgrade to webpack 3

* Update yarn lock

* Update snapshot

* Set prod env when analyzing bundle

* Add jest-cli as dependency

* Revert PR #450 (#451)

Removed change that removed additional dashes in npm test scripts in favor of adding jest-cli as a devDep.

This commit instead focusses on issue 2 from #449 where setupPrompts.js had a bug that caused start script to fail.

* Issue #449 fix (#450)

* Issue #449 fix

Issue 1:
Removed extra dashes located in the package.json test scripts that cause start script to fail.

Issue 2:
Removed escape characters found in setupPrompts.js which cause linting to fail, thus breaking start script.

* Jest fix

Re-added previously removed dashes from test scripts in package.json that caused start script to fail. Instead, @coryhouse added in jest-cli as a dev-dep which resolves the issue.

* Enhance babel env config to transpile for IE9+ (#452)

* Fix for jest handling of static assets when running tests. See: (#457)

jestjs/jest#2663 (comment)

* Added tips for npm run lint and build errors (#151) (#460)

* pushing changes from upstream fetch.

* updated from rebase.

* modified package versions in package.json & created new build.

* update package.json

* fixed conflicts with upstream master.

* cleaned up PropTypes validations - react-router-redux throwing PropTypes error.

* comment spell check & de-console on Root.js
  • Loading branch information
TobiahRex authored and coryhouse committed Sep 3, 2017
1 parent 8d68161 commit 134b5f9
Show file tree
Hide file tree
Showing 17 changed files with 768 additions and 880 deletions.
Empty file added .watchmanconfig
Empty file.
14 changes: 8 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@
"react": "15.5.4",
"react-dom": "15.5.4",
"react-redux": "5.0.5",
"react-router": "3.0.5",
"react-router-redux": "4.0.8",
"react-router": "4.2.0",
"react-router-dom": "4.0.0",
"react-router-redux": "5.0.0-alpha.6",
"redux": "3.6.0",
"redux-thunk": "2.1.0"
},
Expand Down Expand Up @@ -66,6 +67,7 @@
"eslint-watch": "3.1.2",
"extract-text-webpack-plugin": "3.0.0-rc.2",
"file-loader": "0.11.2",
"history": "4.6.0",
"html-webpack-plugin": "2.29.0",
"identity-obj-proxy": "3.0.0",
"jest": "20.0.4",
Expand Down Expand Up @@ -112,10 +114,10 @@
"url": "https://github.com/coryhouse/react-slingshot"
},
"jest": {
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/tools/assetsTransformer.js",
"\\.(css|less)$": "<rootDir>/tools/assetsTransformer.js"
}
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/tools/assetsTransformer.js",
"\\.(css|less)$": "<rootDir>/tools/assetsTransformer.js"
}
},
"babel": {
"presets": [
Expand Down
2 changes: 1 addition & 1 deletion src/components/AboutPage.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import {Link} from 'react-router';
import { Link } from 'react-router-dom';
import '../styles/about-page.css';

// Since this component is simple and static, there's no parent container for it.
Expand Down
2 changes: 1 addition & 1 deletion src/components/AboutPage.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import {shallow} from 'enzyme';
import { shallow } from 'enzyme';
import AboutPage from './AboutPage';

describe('<AboutPage />', () => {
Expand Down
30 changes: 22 additions & 8 deletions src/components/App.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,35 @@
/* eslint-disable import/no-named-as-default */
import React from 'react';
import PropTypes from 'prop-types';
import { Link, IndexLink } from 'react-router';
import { Route } from 'react-router';
import { Switch, NavLink } from 'react-router-dom';
import HomePage from './HomePage';
import FuelSavingsPage from '../containers/FuelSavingsPage';
import AboutPage from './AboutPage';
import NotFoundPage from './NotFoundPage';

// This is a class-based component because the current
// version of hot reloading won't hot reload a stateless
// component at the top-level.

class App extends React.Component {
render() {
const activeStyle = { color: 'blue' };
return (
<div>
<IndexLink to="/">Home</IndexLink>
{' | '}
<Link to="/fuel-savings">Demo App</Link>
{' | '}
<Link to="/about">About</Link>
<br/>
{this.props.children}
<div>
<NavLink exact to="/" activeStyle={activeStyle}>Home</NavLink>
{' | '}
<NavLink to="/fuel-savings" activeStyle={activeStyle}>Demo App</NavLink>
{' | '}
<NavLink to="/about" activeStyle={activeStyle}>About</NavLink>
</div>
<Switch>
<Route exact path="/" component={HomePage} />
<Route path="/fuel-savings" component={FuelSavingsPage} />
<Route path="/about" component={AboutPage} />
<Route component={NotFoundPage} />
</Switch>
</div>
);
}
Expand Down
106 changes: 61 additions & 45 deletions src/components/FuelSavingsForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,48 +32,48 @@ class FuelSavingsForm extends React.Component {
<h2>Fuel Savings Analysis</h2>
<table>
<tbody>
<tr>
<td><label htmlFor="newMpg">New Vehicle MPG</label></td>
<td><FuelSavingsTextInput onChange={this.fuelSavingsKeypress} name="newMpg" value={fuelSavings.newMpg}/>
</td>
</tr>
<tr>
<td><label htmlFor="tradeMpg">Trade-in MPG</label></td>
<td><FuelSavingsTextInput onChange={this.fuelSavingsKeypress} name="tradeMpg" value={fuelSavings.tradeMpg}/>
</td>
</tr>
<tr>
<td><label htmlFor="newPpg">New Vehicle price per gallon</label></td>
<td><FuelSavingsTextInput onChange={this.fuelSavingsKeypress} name="newPpg" value={fuelSavings.newPpg}/>
</td>
</tr>
<tr>
<td><label htmlFor="tradePpg">Trade-in price per gallon</label></td>
<td><FuelSavingsTextInput onChange={this.fuelSavingsKeypress} name="tradePpg" value={fuelSavings.tradePpg}/>
</td>
</tr>
<tr>
<td><label htmlFor="milesDriven">Miles Driven</label></td>
<td>
<FuelSavingsTextInput
onChange={this.fuelSavingsKeypress}
name="milesDriven"
value={fuelSavings.milesDriven}/>
miles per
<select
name="milesDrivenTimeframe"
onChange={this.onTimeframeChange}
value={fuelSavings.milesDrivenTimeframe}>
<option value="week">Week</option>
<option value="month">Month</option>
<option value="year">Year</option>
</select>
</td>
</tr>
<tr>
<td><label>Date Modified</label></td>
<td>{fuelSavings.dateModified}</td>
</tr>
<tr>
<td><label htmlFor="newMpg">New Vehicle MPG</label></td>
<td><FuelSavingsTextInput onChange={this.fuelSavingsKeypress} name="newMpg" value={fuelSavings.newMpg}/>
</td>
</tr>
<tr>
<td><label htmlFor="tradeMpg">Trade-in MPG</label></td>
<td><FuelSavingsTextInput onChange={this.fuelSavingsKeypress} name="tradeMpg" value={fuelSavings.tradeMpg}/>
</td>
</tr>
<tr>
<td><label htmlFor="newPpg">New Vehicle price per gallon</label></td>
<td><FuelSavingsTextInput onChange={this.fuelSavingsKeypress} name="newPpg" value={fuelSavings.newPpg}/>
</td>
</tr>
<tr>
<td><label htmlFor="tradePpg">Trade-in price per gallon</label></td>
<td><FuelSavingsTextInput onChange={this.fuelSavingsKeypress} name="tradePpg" value={fuelSavings.tradePpg}/>
</td>
</tr>
<tr>
<td><label htmlFor="milesDriven">Miles Driven</label></td>
<td>
<FuelSavingsTextInput
onChange={this.fuelSavingsKeypress}
name="milesDriven"
value={fuelSavings.milesDriven}/>
miles per
<select
name="milesDrivenTimeframe"
onChange={this.onTimeframeChange}
value={fuelSavings.milesDrivenTimeframe}>
<option value="week">Week</option>
<option value="month">Month</option>
<option value="year">Year</option>
</select>
</td>
</tr>
<tr>
<td><label>Date Modified</label></td>
<td>{fuelSavings.dateModified}</td>
</tr>
</tbody>
</table>

Expand All @@ -85,11 +85,27 @@ class FuelSavingsForm extends React.Component {
);
}
}
const { func, shape, number, bool, string } = PropTypes;

FuelSavingsForm.propTypes = {
saveFuelSavings: PropTypes.func.isRequired,
calculateFuelSavings: PropTypes.func.isRequired,
fuelSavings: PropTypes.object.isRequired
saveFuelSavings: func.isRequired,
calculateFuelSavings: func.isRequired,
fuelSavings: shape({
newMpg: number,
tradeMpg: number,
newPpg: number,
tradePpg: number,
milesDriven: number,
milesDrivenTimeframe: string,
displayResult: bool,
dateModified: string,
necessaryDataIsProvidedToCalculateSavings: bool,
savings: shape({
monthly: number,
annual: number,
threeYear: number,
}),
}).isRequired
};

export default FuelSavingsForm;
6 changes: 3 additions & 3 deletions src/components/FuelSavingsResults.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ const FuelSavingsResults = ({savings}) => {
return (
<table>
<tbody>
<tr>
<td className="fuel-savings-label">{resultLabel}</td>
<td>
<tr>
<td className="fuel-savings-label">{resultLabel}</td>
<td>
<table>
<tbody>
<tr>
Expand Down
2 changes: 1 addition & 1 deletion src/components/FuelSavingsResults.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import {shallow} from 'enzyme';
import { shallow } from 'enzyme';
import FuelSavingsResults from './FuelSavingsResults';

describe('<FuelSavingsResults />', () => {
Expand Down
14 changes: 8 additions & 6 deletions src/components/FuelSavingsTextInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ const FuelSavingsTextInput = (props) => {
);
};

const { string, func, number, oneOfType } = PropTypes;

FuelSavingsTextInput.propTypes = {
name: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
placeholder: PropTypes.string,
value: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
name: string.isRequired,
onChange: func.isRequired,
placeholder: string,
value: oneOfType([
string,
number
])
};

Expand Down
2 changes: 1 addition & 1 deletion src/components/FuelSavingsTextInput.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import {shallow} from 'enzyme';
import { shallow } from 'enzyme';
import FuelSavingsTextInput from './FuelSavingsTextInput';

describe('<FuelSavingsTextInput />', () => {
Expand Down
4 changes: 2 additions & 2 deletions src/components/HomePage.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import {Link} from 'react-router';
import { Link } from 'react-router-dom';

const HomePage = () => {
return (
Expand All @@ -8,7 +8,7 @@ const HomePage = () => {

<h2>Get Started</h2>
<ol>
<li>Review the <Link to="fuel-savings">demo app</Link></li>
<li>Review the <Link to="/fuel-savings">demo app</Link></li>
<li>Remove the demo and start coding: npm run remove-demo</li>
</ol>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/NotFoundPage.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { Link } from 'react-router';
import { Link } from 'react-router-dom';

const NotFoundPage = () => {
return (
Expand Down
8 changes: 5 additions & 3 deletions src/components/Root.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { ConnectedRouter } from 'react-router-redux';
import { Provider } from 'react-redux';
import routes from '../routes';
import { Router } from 'react-router';
import App from './App';

export default class Root extends Component {
render() {
const { store, history } = this.props;
return (
<Provider store={store}>
<Router history={history} routes={routes} />
<ConnectedRouter history={history}>
<App />
</ConnectedRouter>
</Provider>
);
}
Expand Down
12 changes: 2 additions & 10 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,13 @@

import React from 'react';
import { render } from 'react-dom';
import { browserHistory } from 'react-router';
import { AppContainer } from 'react-hot-loader';
import configureStore, { history } from './store/configureStore';
import Root from './components/Root';

import configureStore from './store/configureStore';
require('./favicon.ico'); // Tell webpack to load favicon.ico
import './styles/styles.scss'; // Yep, that's right. You can import SASS/CSS files too! Webpack will run the associated loader and plug this into the page.
import { syncHistoryWithStore } from 'react-router-redux';

require('./favicon.ico'); // Tell webpack to load favicon.ico
const store = configureStore();

// Create an enhanced history that syncs navigation events with the store
const history = syncHistoryWithStore(browserHistory, store);


render(
<AppContainer>
<Root store={store} history={history} />
Expand Down
2 changes: 1 addition & 1 deletion src/reducers/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { combineReducers } from 'redux';
import fuelSavings from './fuelSavingsReducer';
import {routerReducer} from 'react-router-redux';
import { routerReducer } from 'react-router-redux';

const rootReducer = combineReducers({
fuelSavings,
Expand Down
11 changes: 9 additions & 2 deletions src/store/configureStore.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import {createStore, compose, applyMiddleware} from 'redux';
import reduxImmutableStateInvariant from 'redux-immutable-state-invariant';
import thunk from 'redux-thunk';
import createHistory from 'history/createBrowserHistory';
// 'routerMiddleware': the new way of storing route changes with redux middleware since rrV4.
import { routerMiddleware } from 'react-router-redux';
import rootReducer from '../reducers';

export const history = createHistory();
function configureStoreProd(initialState) {
const reactRouterMiddleware = routerMiddleware(history);
const middlewares = [
// Add other middleware on this line...

// thunk middleware can also accept an extra argument to be passed to each thunk action
// https://github.com/gaearon/redux-thunk#injecting-a-custom-argument
thunk,
reactRouterMiddleware,
];

return createStore(rootReducer, initialState, compose(
Expand All @@ -19,6 +24,7 @@ function configureStoreProd(initialState) {
}

function configureStoreDev(initialState) {
const reactRouterMiddleware = routerMiddleware(history);
const middlewares = [
// Add other middleware on this line...

Expand All @@ -28,6 +34,7 @@ function configureStoreDev(initialState) {
// thunk middleware can also accept an extra argument to be passed to each thunk action
// https://github.com/gaearon/redux-thunk#injecting-a-custom-argument
thunk,
reactRouterMiddleware,
];

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; // add support for Redux dev tools
Expand All @@ -49,4 +56,4 @@ function configureStoreDev(initialState) {

const configureStore = process.env.NODE_ENV === 'production' ? configureStoreProd : configureStoreDev;

export default configureStore;
export default configureStore;
Loading

0 comments on commit 134b5f9

Please sign in to comment.