封装react-redux中的connect

每个组件引入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一个状态

猜你喜欢

转载自blog.csdn.net/zrexam/article/details/88539764