reducer整个应用只有一个,如果应用复杂,reducer就会变得非常庞大。特别是组件,因为只有一个reducer,整个应用也只有一个store,组件一多了之后,维护这个reducer就会更加庞大,这样就更不好维护了,所以需要对reducer拆分。
将redux独立出来的步骤:
1、新建一个组件,写一个reducer,例如 : magicNumRedux.js
这个文件只描述对应组件需要的状态。
// action type
const CHANGE_MAGIC_NUMBER = 'CHANGE_MAGIC_NUMBER/rdx/magicNum'
const initState = { //初始化state
magicNum : Math.random(),
title:'变变变'
}
// actionCreators
let changeMagicNum = ()=>dispatch=>{
dispatch({
type:CHANGE_MAGIC_NUMBER,
val : Math.random()
})
}
function magicNum(state=initState,action){
let {
type,
val
} = action
switch(type){
case 'CHANGE_MAGIC_NUMBER':
return { // return一个对象,确保不会影响原对象
...state,
magicNum : val
}
break;
default:
return state
}
}
2、第一步我们已经新建了一个redux文件,怎么使用?
用起来也非常简单,首先需要在组件内引入这个文件,
然后请看以下代码:
function reducer(state={},action){
return{
counter : counter(state.counter,action),
magicNum : magicNum(state.magicNum,action)
}
}
解读:整个应用只有一个state,state从哪里来的,是从reducer里面来的,reducer返回的是什么,应用的状态就是什么(因为reducer返回的是state状态)。现在我们用reducer这个函数返回了一个对象,这个对象就是应用的状态,这个对象由两个属性构成:counter,magicNum。counter的数据怎么来的?是通过cunter函数返回的state来的(counter返回的是一个数字);magicNum返回的是一个对象。所以最后这个应用的state就是以下这样一个对象
{
counter : counter(state.counter,action),
magicNum : {title:'',magicNum:0 }
}
3、这个时候我们在对应的组件中如何获取这个‘包装’好的state呢?
在组件内使用高阶组件connect,获取传过来的state,展开你要的对象,通过props获取即可。
但是,如果reducer很多很多,只能手动这样合并了,这个时候combineReducers就可以帮我们做这件事情:合并小的reducer,变成一个大的reducer,接收一个对象:
let reducer = combineReducers({
counter,
magicNum
})
在组件内获取state:
export default connect(
(state)=>{ //store.getState()
return {
count : state.counter
}
},
(dispatch)=>bindActionCreators({
...countActions,
changeMagicNum(){
return {
type : 'CHANGE_MAGIC_NUMBER',
val:Math.random()
}
}
},dispatch)
)(Counter)