REACT-REDUX
REACT-REDUX 是把redux进一步封装,适配react项目,让redux操作更简洁
- STORE文件夹中的内容和REDUX一模一样
- 在组件调取使用的时候可以优化一些步骤
与传统的react相比
导出的不在是我们创建的组件,而是基于CONNECT构造后的高阶组件
1
export default connect([mapStateToProps], [mapDispatchToProps])([自己创建的组件])
以前我们基于SUBSCRIBE向事件池追加方法,如果容器状态信息发生改变,就会执行事件池里面的方法,达到组件重新渲染的目的;
- REACT-REDUX帮我们优化redux的使用:“所有用到REDUX容器状态信息的组件,都会向事件池中追加一个方法,当状态信息改变,通知方法执行,把最新的状态信息作为属性传递给组件,组件的属性值改变了,组件也会重新渲染”
Provider 根组件
作用就是把创建的STORE可以供内部任何后代组件使用(基于上下文完成的)
connect 高阶组件
1 | export default connect([mapStateToProps], [mapDispatchToProps])([自己创建的组件]) |
VoteBase
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
79import React from 'react';
import {connect} from 'react-redux';
import action from '../../store/action'
/*
* 相对于传统的REDUX,我们做的步骤优化
* 1. 导出的不在是我们创建的组件,而是基于CONNECT构造后的高阶组件
* export default connect([mapStateToProps], [mapDispatchToProps])([自己创建的组件]);
*
* 2. REACT-REDUX帮我们做了一件非常重要的事情:以前我们需要自己基于SUBSCRIBE向事件池追加方法,以达到容器状态信息改变,执行我们追加的方法,重新渲染组件的目的,但是现在不用了,REACT-REDUX帮我们做了这件事:“所有用到REDUX容器状态信息的组件,都会向事件池中追加一个方法,当状态信息改变,通知方法执行,把最新的状态信息作为属性传递给组件,组件的属性值改变了,组件也会重新渲染”
*/
class VoteBase extends React.Component {
/*constructor(props) {
super(props);
/!*
* 真实项目中我们会把REDUX容器中的状态信息获取到,赋值给组件的状态或者是属性(REACT-REDUX),这么做的目的是:当REDUX中的状态改变,我们可以修改组件内部的状态,从而达到重新渲染组件的目的
*!/
let reduxState = this.props.store.getState().vote;
this.state = {
...reduxState //=>包含title/n/m所有管理的属性
};
}
//=>在第一次加载执行,通过行为派发(VOTE_INIT)把REDUX中的信息赋值初始值
componentWillMount() {
this.props.store.dispatch(action.vote.init({
title: '我长的帅不帅!',
n: 0,
m: 100
}));
let reduxState = this.props.store.getState().vote;
this.setState({...reduxState});
}
//=>向发布订阅事件池中追加一个方法:监听REDUX容器中状态改变,状态改变重新渲染组件
componentDidMount() {
this.props.store.subscribe(() => {
let reduxState = this.props.store.getState().vote;
this.setState({...reduxState});
});
}*/
constructor(props) {
super(props);
console.log(this.props);
}
componentWillMount() {
this.props.init({
title: '我长的帅不帅?',
n: 0,
m: 100
});
}
render() {
let {title, n, m} = this.props;
return <div className='panel panel-default'>
<div className='panel-heading'>
<h3 className='panel-title'>
{title}
</h3>
</div>
<div className='panel-body'>
支持人数:<span>{n}</span>
<br/><br/>
反对人数:<span>{m}</span>
</div>
</div>;
}
}
export default connect(state => ({...state.vote}), action.vote)(VoteBase);//=>REACT-REDUX帮我们做了一件事情,把ACTION-CREATOR中编写的方法(返回ACTION对象的方法),自动构建成DISPATCH派发任务的方法,也就是mapDispatchToProps这种格式
VoteHandle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22import React from 'react';
import {connect} from 'react-redux';
import action from '../../store/action';
class VoteHandle extends React.Component {
constructor(props) {
super(props);
}
render() {
let {support, against} = this.props;
return <div className='panel-footer'>
<button className='btn btn-success' onClick={support}>支持
</button>
<button className='btn btn-danger' onClick={against}>反对
</button>
</div>;
}
}
export default connect(state => ({...state.vote}), action.vote)(VoteHandle);
action
ACTION中处理的事情暂时感觉很无聊:就是封装几个方法(都是需要DISPATCH派发任务修改状态时候执行的方法),方法返回的是当前派发任务时候传递的ACTION对象
REACT-REDUX中才会体验到这个封装的乐趣
action-types
1
2
3
4
5
6//=>VOTE
export const VOTE_INIT = 'VOTE_INIT';//=>数据初始化
export const VOTE_SUPPORT = 'VOTE_SUPPORT';//=>支持
export const VOTE_AGAINST = 'VOTE_AGAINST';//=>反对
//=>PERSONAL
index.js
1
2
3
4
5
6
7
8import vote from './vote';
// import personal from './personal';
let action = {
vote
// personal
};
export default action;
vote.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21import * as TYPE from '../action-types';
let vote = {
support(){
return {
type: TYPE.TYPE.VOTE_SUPPORT
}
},
against() {
return {
type: TYPE.VOTE_AGAINST
};
},
init(initData = {}) {
return {
type: TYPE.VOTE_INIT,
...initData
};
}
}
export default vote;
reducer
index.js
合并REDUCER,为了保证每一个版块管理的状态信息不冲突,在REDUX中按照指定的名称单独划分版块的状态
1
2
3
4
5
6
7
8
9
10 {
vote:{
title:'',
n:0,
m:0
},
personal:{
//=>以合并时候指定的属性名为主,作为最后划分管理的名字
}
}
1 | import { combineReducers } from 'react'; |
vote
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
31import * as TYPE from '../action-types';
/*
* 1. 如果REDUX中原有的状态不存在,我们会设置一个初始值
*/
export default function vote(state={
title: '',
n: 0,
m: 0
},action){
switch(action.type){
case TYPE.VOTE_SUPPORT:
state = {...state,n:state.n + 1}
break;
case TYPE.VOTE_AGAINST:
state = {...state, m: state.m + 1};
break;
case TYPE.VOTE_INIT:
//=>初始化的时候ACTION行为对象中可能不仅有TYPE,而且还有其它需要初始化的信息值,例如:{TYPE:...,TITLE:xxx,N:xx,M:xx...}
/*state = {...state};
for (let attr in action) {
if (action.hasOwnProperty(attr)) {
if (attr === 'type') continue;
state[attr] = action[attr];
}
}*/
let {title = '', n = 0, m = 0} = action;
state = {...state, title, n, m};
break;
}
}