React redux
redux的工作流程:
store创建的三个原则
store是唯一的
只有store才能改变自己的内容
Reducer必须是纯函数(纯函数指的是:给固定的输入,就一定会有固定的输出,而且不会有任何副作用)
项目目录结构:
TodoList.js
import React,{ Component } from 'react';
import 'antd/dist/antd.css';
import { Input,Button,List } from 'antd';
import store from './store/index.js'
import { getInputChangeAction,getAddItemAction,getDeteleItemAction } from './store/actionCreators.js'
// import { CHANGE_INPUT_VALUE,ADD_TODO_ITEM,DELETE_TODO_ITEM } from './store/actionTypes.js'
class TodoList extends Component{
constructor(props){
super(props)
// Store对象包含所有数据。如果想得到某个时点的数据,就要对 Store 生成快照。这种时点的数据集合,就叫做 State。当前时刻的 State,可以通过store.getState()拿到。
this.state = store.getState()
this.handleInputValue = this.handleInputValue.bind(this);
this.handleBtnClick = this.handleBtnClick.bind(this);
this.handleStoreChange = this.handleStoreChange.bind(this);
// Store 允许使用store.subscribe方法设置监听函数,一旦 State 发生变化,就自动执行这个函数。
store.subscribe(this.handleStoreChange)
}
render () {
return (
<div style={{marginTop:'10px'}}>
<div>
<Input
value={this.state.inputValue}
placeholder="todo info"
style={ {width:'300px',marginRight:'10px'} }
onChange={this.handleInputValue}
/>
<Button type="primary" onClick={ this.handleBtnClick }>Primary</Button>
</div>
<List
style={{marginTop:'30px',width:'300px'}}
bordered
dataSource={this.state.list}
renderItem={(item,index) => (<List.Item onClick={ this.handleItemDelete.bind(this,index) }>{item}</List.Item>)}
/>
</div>
)
}
handleInputValue(e){
// const action = {
// type: CHANGE_INPUT_VALUE,
// value: e.target.value
// }
const action = getInputChangeAction(e.target.value)
// store.dispatch()是 View 发出 Action 的唯一方法
store.dispatch(action)
}
handleBtnClick(){
// const action = {
// type: ADD_TODO_ITEM,
// }
const action = getAddItemAction()
store.dispatch(action)
}
handleItemDelete(index){
// const action = {
// type: DELETE_TODO_ITEM,
// index
// }
const action = getDeteleItemAction(index)
store.dispatch(action)
}
handleStoreChange(){
console.log("store change")
this.setState(store.getState())
}
}
export default TodoList;
store目录下的index.js
import { createStore } from 'redux';
import reducer from './reducer'
//创建仓库
// Redux 提供createStore这个函数,用来生成 Store
const store = createStore(reducer)
export default store;
store目录下的reducer.js
import { CHANGE_INPUT_VALUE,ADD_TODO_ITEM,DELETE_TODO_ITEM } from './actionTypes.js'
const defaultState = {
inputValue: '',
list: []
}
// state整个store存放的数据
// action
// reducer 可以接收state,但不能修改state
export default (state=defaultState,action) => {
console.log(state,action)
if(action.type === CHANGE_INPUT_VALUE){
const newState = JSON.parse(JSON.stringify(state)) //深拷贝
newState.inputValue = action.value
return newState
}
if(action.type === ADD_TODO_ITEM){
const newState = JSON.parse(JSON.stringify(state)) //深拷贝
newState.list.push(newState.inputValue)
newState.inputValue = '';
return newState
}
if(action.type === DELETE_TODO_ITEM){
const newState = JSON.parse(JSON.stringify(state)) //深拷贝
newState.list.splice(action.index,1)
return newState
}
return state
}
store目录下的actionTypes.js
export const CHANGE_INPUT_VALUE = 'change_input_value'
export const ADD_TODO_ITEM = 'add_todo_item'
export const DELETE_TODO_ITEM = 'delete_todo_item'
store目录下的actionCreators.js
import { CHANGE_INPUT_VALUE,ADD_TODO_ITEM,DELETE_TODO_ITEM } from './actionTypes.js'
export const getInputChangeAction = (value) => ({
type: CHANGE_INPUT_VALUE,
value
})
export const getAddItemAction = () => ({
type: ADD_TODO_ITEM,
})
export const getDeteleItemAction = (index) => ({
type: DELETE_TODO_ITEM,
index
})