每个组件引入connect后,发现会把当前store中的state都读取监听到,而且每次只要有一个state修改就会运行render的重新渲染,这样大大的降低了页面的效率,所以考虑了一下,可不可以把connect重新封装一下,让每个页面只读取自己需要的state状态!
先在group文件夹中新建一个文件叫GroupState.js
我们要把要用到的connect、bindActionCreators和actioncreators引入一下
import {connect} from "react-redux"
import {bindActionCreators} from "redux"
import actionCreators from "./actionCreators" //自己建的文件 如下
因为connect中dispatch提交时要用到actionCreators,所以我们要把他们整理在一个文件中方便引入,命名为actionCreators.js
import GroupCommons from "../../store/commons/actionCreators" //这是我自己写的测试的store文件
import GroupHome from "../../store/home/actionCreators"//这是我自己写的测试的store文件
export default {
commons: GroupCommons,
home: GroupHome
}
封装好以后,我们接着写GroupState.js,下面才是connect的封装:
//UIComponent是你要用的UI组件
//options是一个对象里面传的两个参数,一个是reducer(你要用哪个store库) 一个是states(要用store库中的哪个state,是一个数组)
//例:options:{reducer:"home", options:['banners','navs']}
const GroupState = (UIComponent,options) =>{
return connect(state=>{
if(!options) return state //如果第二个参数不传,则返回所有库中的所有state
let {states,reducer} = options
if(!states) return state[reducer]
let _state = {}
states.forEach(item => {
_state[item] = state[reducer][item]
})
return _state
},dispatch=>{
let actions = {}
if(!options || !options.reducer){ //如果第二个参数不传,则返回所有库中所有的actionCreators中的方法
for(var key in actionCreators){
//for(var k in actionCreators[key]){
// actions[k] = actionCreators[key][k]
//}
actions = {...actions,...actionCreators[key]} //用的...展开 相当于上面注释的
}
}else{
actions = actionCreators[options.reducer]
}
return bindActionCreators(actions,dispatch)
})(UIComponent)
}
export default GroupState
这样我们就封装好了,可以直接引入用了!
这是模拟调用的方法
import React,{Component} from "react"
import GroupState from "../../modules/group" //先引入进来
class Banner extends Component {
render(){
return (
<div>
这里是banner的信息{this.props.banners}
</div>
)
}
}
export default GroupState(Banner,{
reducer:"home",
states:["banners"]
});
//我们这个banner组件只用到了banners 所以states中只传banners 而banners是在home库中的 所以reducer传home 这样就可以保证这个页面中props只有banner一个状态