redux是一个状态管理工具,一般在多交互,多数据源的时候使用redux编写程序的时候方便很多,代码结构也更加清晰。
以下是广为流传的redux工作流程图
以上的流程我个人理解是:
是一个修改store数据的一个流程图,首先组件中的某个操作需要修改store的数据,然后就要通知store,组件就先将要修改的事情告诉action,通过store.dispatch(action)传给store,store知道这件事之后,就将当前的数据和传过来的action一并传给reducers,reducers接收到这两个参数,通过action的type属性知道要对state做什么修改,修改好之后,将最新的state传给store,然后组件通过store.subscribe()监听到数据发生了变化,就通过store.getState()方法在赋值给组件的state,然后组件就能获取到最新的state了。
在项目中创建并使用
1 :创建一个store文件夹,然后创建一个index.js,这个文件夹是用来创建唯一的store的,再创建一个reducer.js文件,将reducer引入index.js中
store->index.js
// 创建一个store
import {createStore } from 'redux'
import reducer from './reducer'
const store = createStore(
reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
export default store
store->reducer.js
注意:因为store的数据是不能修改的,所以在reducer中需要深拷贝一份store数据,在进行修改,将修改好的数据return
// 这是action的type
import {CANGE_INPUT_VALUE,ADD_TODO_ITEM,DELETE_TODO_ITEM} from './actionTypes'
// state的数据
const defalutState ={
defalutValue:'123',
list:['1','2','3']
}
// reducer是一个纯函数,给定固定的输入,就一定会有固定的输出,而且不会有任何的副作用
export default (state=defalutState,action)=>{
// 匹配action.type作相应的数据操作,这是更换defalutValue的值
if(action.type===CANGE_INPUT_VALUE){
// 深拷贝
const newState = JSON.parse(JSON.stringify(state))
newState.defalutValue = action.value
return newState
}
return state
}
store->actionTypes.js
export const CANGE_INPUT_VALUE = 'chang_input_value'
2.创建好以上文件就可以在组件中获取store的数据了,使用store.getState()获取store的数据
constructor(props){
super(props)
this.state = store.getState()
}
// 使用
render(){
return (
<input value={this.state.defalutValue}>
)
}
3.如果改变input的值的话,就需要创建一个action,将改变的值传给store,然后就是做index.js->reducer.js的内容
constructor(props){
super(props)
this.state = store.getState()
this.handelChangeInput = this.handelChangeInput.bind(this)
}
// 监听onChange事件
input value={this.state.defalutValue} onChange={this.handelChangeInput}>
handelChangeInput(e){
// 创建一个action,将要做的事和值通过dispatch传给store
const action = getHandelChangeInput(e.target.value)
store.dispatch(action)
}
以上getHandelChangeInput方法是封装的一个action,单独写到一个js文件中
store->actionCreators.js
import {CANGE_INPUT_VALUE,ADD_TODO_ITEM,DELETE_TODO_ITEM} from './actionTypes'
export const getHandelChangeInput = (value)=>({
type:CANGE_INPUT_VALUE,
value
});
这时页面上输入值,store的值是变化的,但是页面没显示出来,这时候怎么做到让输入的值,页面也马上显示对应的值呢,通过store.subscribe()订阅store的改变,只要store发生改变自定义的函数就会调用一次
组件代码:
constructor(props){
super(props)
this.state = store.getState()
this.handeStoreChange = this.handeStoreChange.bind(this)
// 这是订阅store的改变,只要store发生改变自定义的函数(this.handeStoreChange)就会调用一次
store.subscribe(this.handeStoreChange)
}
// 监听store的改变
handeStoreChange(){
//当store发生改变的时候,就重新用store.getState()获取一下数据,替换掉state的数据,页面就发生了联动
this.setState(store.getState())
}
这样子就是一个redux的工作流
看一下store的目录结构吧
最后store里的几个重要的API
- createStore:创建store
- store.dispatch() :帮我们派发action,action的内容会传递给store
- store.getState():获取store里的所有数据
- store.subscribe():订阅store的改变,只要store发生改变这个函数接收的回调函数就会被执行