Объяснение Redux на понятном языке


Что это за Redux и зачем он нужен



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import { createStore } from 'redux';

const initialState = {
name: 'Pert',
lastName: 'Petrov'
};

function reducer(state = initialState, action) {
switch (action.type) {
case 'CHANGE_NAME':
return { ...state, name: action.payload };

    case 'CHANGE_LAST_NAME':
      return { ...state, lastName: action.payload };

}

return state;
}

const store = createStore(reducer);

console.log(store.getState());

const changeName = {
type: 'CHANGE_NAME',
payload: 'Ivan'
};

const changeLastName = {
type: 'CHANGE_LAST_NAME',
payload: 'Ivanov'
};

store.dispatch(changeName);

console.log(store.getState());

store.dispatch(changeLastName);

console.log(store.getState());


React и Redux. Подключаемся к Redux



.babelrc


1
2
3
{
"presets": ["react", "es2015", "stage-2"]
}


webpack.config.js


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
---

module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
]
},

---



index.js


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import { connect, Provider } from 'react-redux';

const initialState = {
firstName: 'Ivan',
lastName: 'Ivanov'
};

const ACTION_CHANGE_FIRST_NAME = 'ACTION_CHANGE_FIRST_NAME';
const ACTION_CHANGE_LAST_NAME = 'ACTION_CHANGE_LAST_NAME';

const changeFirstName = newFirstName => {
console.log(newFirstName);

return {
type: ACTION_CHANGE_FIRST_NAME,
payload: newFirstName
};
};

const changeLastName = newLastName => {
return {
type: ACTION_CHANGE_LAST_NAME,
payload: newLastName
};
};

const rootReducer = (state = initialState, action) => {
switch (action.type) {
case ACTION_CHANGE_FIRST_NAME:
return { ...state, firstName: action.payload };

    case ACTION_CHANGE_LAST_NAME:
      return { ...state, lastName: action.payload };

}

return state;
};

const store = createStore(rootReducer);

class MainComponent extends React.Component {
render() {
console.log('MainComponent props');
console.log(this.props);

    const dispatch = this.props.dispatch;
    const { firstName, lastName } = this.props;

    return (
      <div>
        <div>
          <input
            type="text"
            value={firstName}
            placeholder="First Name"
            onChange={event => {
              dispatch(changeFirstName(event.target.value));
            }}
          />{' '}
        </div>
        <div>
          <input
            type="text"
            value={lastName}
            placeholder="Last Name"
            onChange={event => {
              dispatch(changeLastName(event.target.value));
            }}
          />{' '}
        </div>

        <div>{`${firstName} ${lastName}`}</div>
      </div>
    );

}
}
const mapStateToProps = state => {
return {
firstName: state.firstName,
lastName: state.lastName
};
};

const WrappedMainComponent = connect(mapStateToProps)(MainComponent);

ReactDOM.render(
<Provider store={store}>
<WrappedMainComponent />
</Provider>,
document.getElementById('app')
);


Улучшаем


index.js


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, bindActionCreators } from 'redux';
import { connect, Provider } from 'react-redux';

const initialState = {
firstName: 'Ivan',
lastName: 'Ivanov'
};

const ACTION_CHANGE_FIRST_NAME = 'ACTION_CHANGE_FIRST_NAME';
const ACTION_CHANGE_LAST_NAME = 'ACTION_CHANGE_LAST_NAME';

const changeFirstName = newFirstName => {
console.log(newFirstName);

return {
type: ACTION_CHANGE_FIRST_NAME,
payload: newFirstName
};
};

const changeLastName = newLastName => {
return {
type: ACTION_CHANGE_LAST_NAME,
payload: newLastName
};
};

const rootReducer = (state = initialState, action) => {
switch (action.type) {
case ACTION_CHANGE_FIRST_NAME:
return { ...state, firstName: action.payload };

    case ACTION_CHANGE_LAST_NAME:
      return { ...state, lastName: action.payload };

}

return state;
};

const store = createStore(rootReducer);

class MainComponent extends React.Component {
render() {
console.log('MainComponent props');
console.log(this.props);

    const dispatch = this.props.dispatch;
    const { firstName, lastName, changeFirstName, changeLastName } = this.props;

    return (
      <div>
        <div>
          <input
            type="text"
            value={firstName}
            placeholder="First Name"
            onChange={event => {
              changeFirstName(event.target.value);
            }}
          />{' '}
        </div>
        <div>
          <input
            type="text"
            value={lastName}
            placeholder="Last Name"
            onChange={event => {
              changeLastName(event.target.value);
            }}
          />{' '}
        </div>

        <div>{`${firstName} ${lastName}`}</div>
      </div>
    );

}
}
const mapStateToProps = state => {
return {
firstName: state.firstName,
lastName: state.lastName
};
};

// putActionsToProps
const mapDispatchToProps = dispatch => {
return {
changeFirstName: bindActionCreators(changeFirstName, dispatch),
changeLastName: bindActionCreators(changeLastName, dispatch)
};
};

const WrappedMainComponent = connect(
mapStateToProps,
mapDispatchToProps
)(MainComponent);

ReactDOM.render(
<Provider store={store}>
<WrappedMainComponent />
</Provider>,
document.getElementById('app')
);