Объяснение 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
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
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
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')
);