Redux笔记

React数据流状态管理工具,各组件之间的数据交互管理者:Redux笔记.

Redux工作流知识

他山之石

快递思想

Redux flow

入门理解与代码

创建store:

创建store目录,内部创建index.js文件,并且编辑内容:

1
2
3
4
5
6
7
8
9
import {createStore} from 'redux'

// 数据来源reducer,内部初始化的值
import reducer from './reducer'

//传入创建store方法
const store = createStore(reducer)

export default store

继续在此目录下创建reducer.js并且编辑:

1
2
3
4
5
6
7
8
9
// 默认数据仓库对象的数据
const defaultState = {
inputValue: '添加list事件',
list: [0,1,3]
}

export default (state=defaultState, action) => {
return state
}

总之store的数据来源是reducer,而UI的数据来源是store!

编写action
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { CIV, SUBMIT, DELETE } from './actionTypes'

export const changeInputValue = (value) => ({
type: CIV,
value
})

export const submitNewEvent = () => ({
type: SUBMIT
})

export const deleteTodoItem = (index) => ({
type: DELETE,
index
})

通过编写封装的创建action代码,便于未来的自动化测试.

编写reducer
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
// 默认数据仓库对象的数据
const defaultState = {
inputValue: '',
list: []
}

// store Dispatch过来的action是一个对象,传入了下面的代码里
// state却是上一次的数据

// state绝对不能修改,默认操作是拷贝一份state
export default (state=defaultState, action) => {
if (action.type === 'civ'){
const newState = Object.assign({}, state)
newState.inputValue = action.value
// 返回的newState给了store
return newState
}
if (action.type === 'submit') {
const newState = Object.assign({}, state)
newState.list = [...newState.list, newState.inputValue]
newState.inputValue = ''
return newState
}
if (action.type === 'delete_todo_item'){
const newState = Object.assign({}, state)
newState.list.splice(action.index, 1)
return newState
}
return state
}
数据订阅
1
store.subscribe(this.handleSubmitEvent)

在组件的构造器内编写store的订阅代码,当store数据更新后,触发订阅函数的参数,这个参数是一个函数.

Redux回顾
  • store的数据,在reducer返回的一个copy的新数据之后,store自我更新数据.
  • store是唯一的,这也是与flux的区别
  • reducer必须是纯函数(给定固定的输入,有固定的输出,并且不能修改其他外部变量,不能有副作用)

附带todolist组件部分的完整代码;

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'
import { Input,List,Button } from 'antd'
import store from './store/index'

import { changeInputValue, submitNewEvent, deleteTodoItem } from './store/actionCreators'


class TodoList extends Component {

constructor(props) {
super(props)
this.state = store.getState()
this.handleInputChange = this.handleInputChange.bind(this)
this.handleClick = this.handleClick.bind(this)
this.handleSubmitEvent = this.handleSubmitEvent.bind(this)
store.subscribe(this.handleSubmitEvent)
}

handleSubmitEvent(){
this.setState(store.getState())
}

handleInputChange(e){
// 告诉store,修改内部数据
const action = changeInputValue(e.target.value)
store.dispatch(action)
}

handleClick(){
const inputValue = store.getState().inputValue
if (inputValue !== '') {
const action = submitNewEvent()
store.dispatch(action)
}
}

handleItemDelete(index){
const action = deleteTodoItem(index)
store.dispatch(action)
}

render (){
return (
<div>
<div style={{width: '60%', margin: '20px auto'}}>
<Input
placeholder="添加事件"
style={{maxWidth: "87.5%", marginRight: "5px"}}
onChange={this.handleInputChange}
value={this.state.inputValue}
/>
<Button type="primary" onClick={this.handleClick}>添加</Button>
<div>
<List
header={<div>所有事项</div>}
footer={<div>......</div>}
bordered
dataSource={this.state.list}
renderItem={(item, index)=> (<List.Item onClick={this.handleItemDelete.bind(this, index)}>{item}</List.Item>)}
/>
</div>
</div>
</div>
)
}
}

export default TodoList

ANT DESIGN

重点问题:出现了样式失效的问题.

在create-react-app中使用参见

待续吧,在以后的项目中一定会使用antd,到时候再更新一些笔记.