前言

eg:代表代码对照 若文章有误,欢迎读者留言反馈

Redux学习【store】

配置store

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
/*
store 类似vue中的store, 项目中唯一的仓库

安装redux
npm i -S redux
*/

// 引入createStore
import {createStore} from 'redux'

// store存储数据,要遵循不可变值,不能直接修改此state
const defaultState = {
num: 0
}

// reducer 函数逻辑,如果修改state的逻辑,初始化还是修改都是返回一个新的state
// 参数1 把默认的state传入 参数2 actions是我们的触发规则
// reducer执行多次,只要你触发actions就会执行reducer
const reducer = (state = defaultState, actions) => {
// 这里也可以使用switch,redux的state和setState两者覆盖区别,setState是合并而redux的则是整个state覆盖,为了避免新的state覆盖旧的state造成属性丢失,我们可以加上...state。
if (actions.type == 'addHandle') {
return {num: actions.add + state.num} // 返回新的state
}
return state // 初始化的时候返回新的state
}

// 传入reducer函数逻辑
const store = createStore(reducer)
export default store

ReduxDemo.jsx代码:

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
import React, { Component } from 'react'
// 学习的案例,项目中把store放在入口文件中
import store from '../store/index'
export default class ReduxDemo extends Component {
constructor(props) {
super(props)
this.state = store.getState() // 获取redux中的state
// 加一个监听redux state改变的函数
store.subscribe(() => {
this.setState(() => store.getState()) // 当redux中state改变的时候,自动更新当前的state
})
}
handleClick = () => {
// 同步的actions对象,type是规则,type的值要和reducer中的actions.type对应即可
const userActions = { type: 'increhander', incre: 1 }
store.dispatch(userActions) //store.dispatch(actions对象) 调用reducer中的代码逻辑
}
render() {
return (
<div>
<h3>redux使用</h3>
<p>{this.state.num}</p>
<button onClick={this.handleClick}>+1</button>
</div>
)
}
}

store已经挂载在全局了,然后我们页面中现在如何使用?

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
import React, { Component } from 'react'
import { connect } from 'react-redux'
// store已经挂载在全局了,然后我们页面中现在如何使用?

class ReduxDemo1 extends Component {
render() {
return (
<div>
<h3>redux使用</h3>
<p>{ this.props.mynum }</p>
<button onClick={ this.props.increseFun }>+2</button>
</div>
)
}
}
// 把redux中的state映射过来,然后放入当前组件props中,通过this.props.属性获取到。
const mapStateToProps = (state) => {
return{
mynum:state.num //this.props.mynum 来调用
}
}
// 把redux中的方法映射过来,然后放入当前组件的props中,通过this.props.方法来调用。
const mapDispatchToProps = (dispatch) => {
return{
increseFun(){ //方法是自己定义的, this.props.increseFun来调用
const myAction = { type:'increhander',incre:2}
dispatch(myAction) //用来触发acitons的
}
}
}
export default connect(mapStateToProps,mapDispatchToProps)(ReduxDemo1)

redux简化版本

规则放到一个文件中

actionTypes.js代码:

1
export const increType = 'home/increhander' //常量 字符串随便

导出刚才不同actions,不同写法:
actions.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

// 导出刚才不同actions 加3操作
// export const myActions = {
// type:'increhander',
// incre:3
// }
import { increType } from './actionTypes'
// actions写法2 函数形式
export const myActions = (val) => {
return {
type:increType, //'increhander',
incre: val
}
}
// redux使用异步的action,需要安装一个包 redux-thunk 中间件
// npm i -S redux-thunk
// 异步actions 2s后执行加5操作
export const myActionsAsync = (val) => {
return (dispatch)=>{
//写异步逻辑,异步actions需要调用通过action才可以进行操作
setTimeout(() => {
dispatch(myActions(5))
}, 2000);
}
}

使用

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
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { myActions, myActionsAsync } from './actions'
//装饰器模式 配置
@connect(
state => ({ // state映射写法
mynum: state.num
}),
dispatch => ({ // dispatch函数映射写法
increfun(val) {
dispatch(myActions(val))
},
increfun2() {
dispatch(myActionsAsync()) // 注意:函数形式的actions别丢失了小括号
}
})
)
class ReduxDemo2 extends Component {
render() {
return (
<div>
<h3>redux使用案例--简化版</h3>
<p>{this.props.mynum}</p>
<button onClick={() => this.props.increfun(4)}>+3</button>
<button onClick={this.props.increfun2}>+5</button>
</div>
)
}
}
export default ReduxDemo2