Skip to content

Commit 7157d6a

Browse files
authored
[release] 1.0.0: 💥 redux, router-redux, redux-saga (#1)
* Сonfigure the Redux + react-redux. Create global store * Сonfigure the react-router + react-router-redux * Сonfigure ESlint * Improved file structure of project * Create App actions and reducer * Create App sagas and selectors for data dowloading * Update README * pre-commit javascript lint
1 parent 345d228 commit 7157d6a

File tree

21 files changed

+825
-76
lines changed

21 files changed

+825
-76
lines changed

.eslintrc.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"extends": "airbnb",
3+
"env": {
4+
"browser": true,
5+
"jest": true
6+
},
7+
"plugins": [
8+
"react",
9+
"jsx-a11y",
10+
"import"
11+
],
12+
"rules": {
13+
"arrow-parens": ["error", "always"],
14+
"react/forbid-prop-types": 0,
15+
"react/jsx-filename-extension": 0
16+
}
17+
}

README.md

Lines changed: 89 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,94 @@
11
# Create react redux app
2-
This project was bootstrapped with [Create React App](https://github.com/facebookincubator/create-react-app).
2+
This project was bootstrapped with [Create React App](https://github.com/facebookincubator/create-react-app).<br>
3+
The project includes extra redux packages and improved file structure.
4+
5+
## Table of Contents
6+
- [Dependencies that was added to app created with create-react-app](#dependencies-that-was-added-to-the-app)
7+
- [Quick start](#quick-start)
8+
- [Improved folder Structure](#improved-folder-structure)
9+
- [Available Scripts](#available-scripts)
10+
- [Table of Contents for react-scripts](
11+
https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md)
12+
13+
## Dependencies that was added to the app
14+
- redux
15+
- react-redux
16+
- redux-saga
17+
- immutable
18+
- react-router-dom
19+
- react-router-redux
20+
21+
devDependencies:
22+
- eslint (based on Airbnb rules)
23+
- pre-commit
24+
25+
## Quick start
26+
**1.** Clone project
27+
```bash
28+
# with SSH
29+
git clone git@github.com:YUzhva/create-react-redux-app.git
30+
31+
# with HTTPS
32+
git clone https://github.com/YUzhva/create-react-redux-app.git
33+
```
34+
35+
**2.** Rename project
36+
```bash
37+
# command for Mac/Linux
38+
mv create-react-redux-app NEW_PROJECT_NAME
39+
40+
# command for Windows
41+
rename create-react-redux-app NEW_PROJECT_NAME
42+
```
43+
44+
**3.** Go inside project folder `cd NEW_PROJECT_NAME` and edit project name inside `package.json`
45+
```javascript
46+
// change
47+
{
48+
"name": "create-react-redux-app",
49+
}
50+
51+
// to the
52+
{
53+
"name": "NEW_PROJECT_NAME",
54+
}
55+
```
356

4-
## Folder Structure
57+
**4.** Delete .git folder
58+
```bash
59+
# command for Mac/Linux
60+
rm -rf .git
561

6-
After creation, your project should look like this:
62+
# command for Windows
63+
rmdir .git
64+
```
65+
66+
**5.** Initialize new git
67+
```bash
68+
git init
69+
git add .
70+
git commit -m "[initial commit] NEW_PROJECT_NAME"
71+
```
72+
73+
:beer: Have fun :beer: (=
74+
75+
## Improved folder Structure
776

877
```
9-
my-app/
10-
README.md
11-
node_modules/
12-
package.json
13-
public/
14-
index.html
15-
favicon.ico
16-
src/
17-
App.css
18-
App.js
19-
App.test.js
20-
index.css
21-
index.js
22-
logo.svg
78+
- src
79+
- components // reusable react components without redux
80+
* ContainerName
81+
tests
82+
index.js // entry point for component
83+
84+
- containers // react components with redux and redux-saga data fetching
85+
* ContainerName
86+
tests
87+
index.js // entry point for container
88+
constants/actions/reducer/sagas/selectors.js // place container required files in root
89+
90+
- global-reducer.js // connect other containers reducers here
91+
- global-sagas.js // connect other containers sagas here
2392
```
2493

2594
For the project to build, **these files must exist with exact filenames**:
@@ -55,6 +124,9 @@ You will also see any lint errors in the console.
55124
Launches the test runner in the interactive watch mode.<br>
56125
See the section about [running tests](#running-tests) for more information.
57126

127+
### `npm run lint`
128+
Lints your JavaScript.
129+
58130
### `npm run build`
59131

60132
Builds the app for production to the `build` folder.<br>

package.json

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,39 @@
33
"version": "0.1.0",
44
"private": true,
55
"dependencies": {
6+
"history": "^4.6.1",
7+
"immutable": "^3.8.1",
8+
"prop-types": "^15.5.10",
69
"react": "^15.5.4",
7-
"react-dom": "^15.5.4"
10+
"react-dom": "^15.5.4",
11+
"react-redux": "^5.0.4",
12+
"react-router-dom": "^4.1.1",
13+
"react-router-redux": "^5.0.0-alpha.6",
14+
"redux": "^3.6.0",
15+
"redux-saga": "^0.15.3"
816
},
917
"devDependencies": {
18+
"eslint": "^3.19.0",
19+
"eslint-config-airbnb": "^14.1.0",
20+
"eslint-plugin-import": "^2.2.0",
21+
"eslint-plugin-jsx-a11y": "4.0.0",
22+
"eslint-plugin-react": "^7.0.0",
23+
"lint-staged": "^3.4.1",
24+
"pre-commit": "^1.2.2",
1025
"react-scripts": "0.9.5"
1126
},
1227
"scripts": {
1328
"start": "react-scripts start",
1429
"build": "react-scripts build",
1530
"test": "react-scripts test --env=jsdom",
16-
"eject": "react-scripts eject"
17-
}
31+
"eject": "react-scripts eject",
32+
"lint": "npm run lint:js",
33+
"lint:staged": "lint-staged",
34+
"lint:js": "eslint --ext .js src/"
35+
},
36+
"pre-commit": "lint:staged",
37+
"lint-staged": {
38+
"*.js": "lint:js"
39+
},
40+
"proxy": "https://httpbin.org"
1841
}

src/App.js

Lines changed: 0 additions & 21 deletions
This file was deleted.

src/components/.keep

Whitespace-only changes.

src/containers/App/actions.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import {
2+
GET_API_DATA,
3+
GET_API_DATA_LOADED,
4+
GET_API_DATA_ERROR,
5+
} from './constants';
6+
7+
export const getAPIData = () => ({
8+
type: GET_API_DATA,
9+
});
10+
11+
export const getAPIDataLoaded = (data) => ({
12+
type: GET_API_DATA_LOADED,
13+
data,
14+
});
15+
16+
export const getAPIDataError = (error) => ({
17+
type: GET_API_DATA_ERROR,
18+
error,
19+
});

src/containers/App/constants.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export const GET_API_DATA = 'containers/App/GET_API_DATA';
2+
export const GET_API_DATA_LOADED = 'containers/App/GET_API_DATA_LOADED';
3+
export const GET_API_DATA_ERROR = 'containers/App/GET_API_DATA_ERROR';
File renamed without changes.

src/containers/App/index.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import React, { Component } from 'react';
2+
import PropTypes from 'prop-types';
3+
import { bindActionCreators } from 'redux';
4+
import { connect } from 'react-redux';
5+
6+
import { getAPIData } from './actions';
7+
import { selectApiData } from './selectors';
8+
9+
import logo from './images/logo.svg';
10+
11+
class App extends Component {
12+
componentWillMount() {
13+
this.props.actions.getAPIData();
14+
}
15+
16+
render() {
17+
return (
18+
<div className="app">
19+
<div className="app-header">
20+
<img src={logo} className="app-logo" alt="logo" />
21+
<h2>Welcome to React</h2>
22+
</div>
23+
<p className="app-intro">
24+
To get started, edit <code>src/App.js</code> and save to reload.
25+
</p>
26+
<p className="app-intro">
27+
Your IP is: {this.props.apiData && this.props.apiData.origin.split(', ')[1]}
28+
</p>
29+
</div>
30+
);
31+
}
32+
}
33+
34+
App.defaultProps = {
35+
apiData: {},
36+
};
37+
38+
App.propTypes = {
39+
actions: PropTypes.object.isRequired,
40+
apiData: PropTypes.object,
41+
};
42+
43+
const mapStateToProps = (state) => ({
44+
apiData: selectApiData(state),
45+
});
46+
47+
const mapDispatchToProps = (dispatch) => ({
48+
actions: bindActionCreators({ getAPIData }, dispatch),
49+
});
50+
51+
export default connect(mapStateToProps, mapDispatchToProps)(App);

src/containers/App/reducer.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { fromJS } from 'immutable';
2+
3+
import {
4+
GET_API_DATA,
5+
GET_API_DATA_LOADED,
6+
GET_API_DATA_ERROR,
7+
} from './constants';
8+
9+
const initialState = fromJS({
10+
apiData: null,
11+
apiDataLoading: null,
12+
apiDataLoaded: null,
13+
apiDataError: null,
14+
});
15+
16+
const appReducer = (state = initialState, action) => {
17+
switch (action.type) {
18+
case GET_API_DATA:
19+
return state
20+
.set('apiDataLoading', true)
21+
.set('apiDataError', null);
22+
case GET_API_DATA_LOADED:
23+
return state
24+
.set('apiData', action.data)
25+
.set('apiDataLoading', false)
26+
.set('apiDataLoaded', true)
27+
.set('apiDataError', null);
28+
case GET_API_DATA_ERROR:
29+
return state
30+
.set('apiDataLoading', false)
31+
.set('apiDataLoaded', false)
32+
.set('apiDataError', action.error);
33+
default:
34+
return state;
35+
}
36+
};
37+
38+
export default appReducer;

0 commit comments

Comments
 (0)