redux 的使用

redux 中文文档

redux 中文文档

redux 原理图

redux原理图
redux 原理图

redux 三大原则

redux 三大原则

  • 单一数据源
    整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中。

  • State 是只读的
    唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。

  • 使用纯函为了
    描述 action 如何改变 state tree ,你需要编写 reducers。

计算器案例

目录结构

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

src
├─components
│ └─Count
│ └─index.jsx
└─redux
│ └─constant.js
│ └─count_action.js
│ └─count_reducer.js
│ └─store.js
└─App.jsx
└─index.js

src/index.js

1
2
3
4
5
6
7
8
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import store from './redux/store'

store.subscribe(() => {
ReactDOM.render(<App />, document.getElementById('root'))
})

src/App.js

1
2
3
4
5
6
7
8
9
10
11
12
import React, { Component } from 'react'
import Count from './components/Count/index'

export default class App extends Component {
render() {
return (
<div>
<Count />
</div>
)
}
}

src/components/Count/index.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
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
import React, { Component } from 'react'
// store 用于获取redux中保存的状态
import store from '../../redux/store'
// action 用于创建action对象
import {
createIncrementAction,
createDecrementAction,
} from '../../redux/count_action'

class Count extends Component {
/*
componentDidMount() {
// 检测redux中状态变化,变化则调用render
store.subscribe(() => {
this.forceUpdate()
// 或者
// this.setState({})
})
}
在index.js最外层包裹store,监测redux中状态的变化
*/

//加法
increment = () => {
const { value } = this.selectNumber
// 通知redux加value redux不会自动更新render
store.dispatch(createIncrementAction(value * 1))
}
//减法
decrement = () => {
const { value } = this.selectNumber
store.dispatch(createDecrementAction(value * 1))
}
// 奇数再加
incrementIfOdd = () => {
const { value } = this.selectNumber
const count = store.getState()
if (count % 2 !== 0) {
store.dispatch(createIncrementAction(value * 1))
}
}
// 异步加
incrementAsync = () => {
const { value } = this.selectNumber
// setTimeout(() => {
store.dispatch(createIncrementAction(value * 1))
// }, 1000);
}
render() {
return (
<div>
<h1>当前求和为:{store.getState()}</h1>
<select ref={(c) => (this.selectNumber = c)}>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
&nbsp; &nbsp;
<button onClick={this.increment}>+</button>&nbsp;&nbsp;
<button onClick={this.decrement}>-</button>&nbsp;&nbsp;
<button onClick={this.incrementIfOdd}>若当前求和为奇数 +</button>&nbsp;&nbsp;
<button onClick={this.incrementAsync}>异步 +</button>&nbsp;&nbsp;
</div>
)
}
}

export default Count

src/redux/constant.js

1
2
3
4
5
/*
该模块用于定义action对象中type类型的常量值
*/
export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'

src/redux/count_action.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
该组件专门为 Count 组件生成 action 对象
*/
import { INCREMENT, DECREMENT } from './constant'

//同步action,就是指action的值为Object类型的一般对象
export const createIncrementAction = (data) => ({ type: INCREMENT, data })
export const createDecrementAction = (data) => ({ type: DECREMENT, data })

//异步action,就是指action的值为函数,异步action中一般都会调用同步action,异步action不是必须要用的。
export const createIncrementAsyncAction = (data, time) => {
return (dispatch) => {
setTimeout(() => {
dispatch(createIncrementAction(data))
}, time)
}
}

src/redux/count_reducer.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
1.该文件是用于创建一个为Count组件服务的reducer,reducer 的本质就是一个函数
2.reducer函数回接到两个参数,分别为:之前的状态(preState),动作对象(action)
*/
import { INCREMENT, DECREMENT } from './constant'

//初始化状态
const initState = 0
export default function countReducer(preState = initState, action) {
// if (preState === undefined) preState = 0
//从action对象中获取:type、data
const { type, data } = action
//根据type决定如何加工数据
switch (type) {
case INCREMENT: //如果是加
return preState + data
case DECREMENT: //如果是减
return preState - data
default:
return preState
}
}

src/redux/store.js

异步 store 需要引入 applyMiddleware

1
2
3
4
5
6
7
8
9
10
11
12
/* 
该文件专门用于暴露一个store对象,整个应用只有一个store对象
*/

//引入createStore,专门用于创建redux中最为核心的store对象
import { createStore, applyMiddleware } from 'redux'
//引入为Count组件服务的reducer
import countReducer from './count_reducer'
//引入redux-thunk,用于支持异步action
import thunk from 'redux-thunk'
//暴露store
export default createStore(countReducer, applyMiddleware(thunk))