由于redux只能做同步操作,如果需要做异步操作,需要借助中间件(redux-thunk 或者 redux-saga,二选一)。
在react中,只要你需要进行状态管理,就需要使用redux;
如果想要在使用redux的基础上简化代码,将业务逻辑和UI组件分离,就需要使用react-redux;
如果要后台进行异步交互,就需要使用redux-thunk 或者 redux-saga。
actionCreator
action制造器,之前我们的action都是直接在组件文件里写的,这样很麻烦。这个时候就可以创建一个actionCreator文件帮我们创造action对象,那要这么写一个actionCreator呢?
在一个actionCreator文件里导出一个函数,比如:
export const getA = (value) => {
return {
type: 'GET_A',
value
}
}
之后就可以在组件文件里引入这个 actionCreator文件,在需要时直接调用getA函数就能创造一个action对象了。
更甚至的,action的type的字符串的值也可以维护成一个文件,好处就是在需要更改时只需改一处,以及更好的排查问题。
reducer合并
在做项目的时候,会有不同的页面,每个页面维护一个reducer,所有一个项目会存在多个reducer,(也就是reducer进行模块化分割,不同模块定义不同的state初始值以及对state的更改),但是我们的store只能绑定一个reducer;这个时候就要把多个小的reducer合并成一个大的reducer,要想合并reducer我们需要使用redux的 combineReducers 方法。
import AReducer from './AReducer’
import BReducer from './BReducer’
import {combineReducers,createStore} from 'redux’
// 合并多个reducer
let rootReducer = combineReducers({
AReducer,
BReducer
})
export default createStore(rootReducer)
这样两个(多个)reducer就合并,但是每个小的reducer都有自己的初始化数据,那初始数据又是怎么样合并的呢? (比如AReducer里有AInitState,BReducer里有BInitState。)
其实合并reducer时,store里的总的state时一个对象,里面有多个属性,属性的key就是合并时的reducer的值,值就时对应reducer的初始state。最终的store的state类似这样的:
state = {
AReducer: {},
BReducer: {}
}
整合后,模块中的数据是可以相互获取的 ,因为获取了store的数据就相当于获取了整合后的数据。
简单实例:
目录结构:
test1Action.js文件
//test1的Action创造器
import {CHANGE_TEST1} from '../actionTypes'
export const changeTest1 = (value)=>{
return {
type:CHANGE_TEST1,
value
}
}
test2Action.js文件
//test2的Action创造器
import {CHANGE_TEST2} from '../actionTypes'
export const changeTest2 = (value)=>{
return {
type:CHANGE_TEST2,
value
}
}
actionTypes.js文件
export const CHANGE_TEST1 = 'CHANGE_TEST1'
export const CHANGE_TEST2 = 'CHANGE_TEST2'
test1Reducer文件
//test1Reducer
import {CHANGE_TEST1} from '../actionTypes'
let test1State={
msg:'test1'
}
const reducer = (state = test1State,action)=>{
if(action.type === CHANGE_TEST1){
return {
...state,
msg:action.value
}
}
return state;
}
export default reducer
test2Reducer文件
//test2Reducer
import {CHANGE_TEST2} from '../actionTypes'
let test2State={
msg:'test2'
}
const reducer = (state = test2State,action)=>{
if(action.type === CHANGE_TEST2){
return {
...state,
msg:action.value
}
}
return state;
}
export default reducer
store --> index.js文件
import { combineReducers, createStore } from 'redux'
import test1Reducer from './reducers/test1Reducer'
import test2Reducer from './reducers/test2Reducer'
//合并reducer
const reducers = combineReducers({
test1:test1Reducer,
test2:test2Reducer
})
//合并后的reducer的初始化数据
/**
{
test1:{
msg:'test1',
},
test2:{
msg:'test2'
}
}
*/
//创建仓库
const store = createStore(reducers)
export default store
pages --> test1.js文件
import React,{Component} from 'react'
import store from '../ store'
import {changeTest1} from '../ store/actionCreators/test1Action'
import {changeTest2} from '../ store/actionCreators/test2Action'
class Test1 extends Component{
constructor(props){
super(props)
this.state = store.getState()
store.subscribe(this.changeState)
}
//监听state
changeState=()=>{
this.setState(store.getState()) //监听到数据变换就马上就新的数据设置给this.state
}
//更改test1数据
changeTest1Value=()=>{
store.dispatch(changeTest1('123'))
}
//更改test2数据
changeTest2Value=()=>{
store.dispatch(changeTest2('456'))
}
render(){
return (
<div>
{JSON.stringify(this.state)}
<button onClick={this.changeTest1Value}>更改test1数据</button>
<button onClick={this.changeTest2Value}>更改test2数据</button>
</div>
)
}
}
export default Test1