React 笔记 6

 REDUX  

REACT-REDUX

 * REACT-REDUX是把REDUX进一步封装,适配REACT项目,让REDUX操作更简洁

 *   STORE文件夹中的内容和REDUX一模一样

 *   在组件调取使用的时候可以优化一些步骤

 *

 *   1.Provider 根组件

 *     当前整个项目都在Provider组件下,用Provider包起来

 *     作用就是把创建的STORE可以供内部任何后代组件使用(基于上下文完成的)

 *

 *     =>Provider组件中只允许出现一个子元素

 *     =>把创建的STORE基于属性传递给Provider(这样后代组件中都可以使用这个STORE了)

render(<Provider store={store}>
    <section className='panel panel-default' style={{width: '50%', margin: '20px auto'}}>
        <VoteBase/>
        <VoteHandle/>
    </section>
</Provider>, root);

 *   2.connect 高阶组件

 * 相对于传统的REDUX,我们做的步骤优化

 *   import {connect} from 'react-redux'

 *   1. 导出的不在是我们创建的组件,而是基于CONNECT构造后的高阶组件

 *   export default connect([mapStateToProps], [mapDispatchToProps])([自己创建的组件]);

//=>把REDUX容器中的状态信息遍历,赋值给当前组件的属性(state)
let mapStateToProps = state => {
    //=>state:就是REDUX容器中的状态信息
    //=>我们返回的是啥,就把它挂载到当前组件的属性上(REDUX存储很多信息,我们想用啥就
    //=>返回啥即可)
    return {
        ...state.vote
    };
};*/


//=>把REDUX中的DISPATCH派发行为遍历,也赋值给组件的属性(ActionCreator)
let mapDispatchToProps = dispatch => {
    //=>dispatch:STORE中存储的DISPATCH方法
    //=>返回的是啥,就相当于把啥挂载到组件的属性上(一般我们挂载一些方法,这些方法中
    //=>完成了DISPATCH派发任务操作)
    return {
        init(initData) {
            dispatch(action.vote.init(initData));
        }
    };
};
export default connect(mapStateToProps, mapDispatchToProps)(VoteBase);
export default connect(state => ({...state.vote}), action.vote)(VoteBase);
//=>REACT-REDUX帮我们做了一件事情,把ACTION-CREATOR中编写的方法(返回ACTION对象
//=>的方法),自动构建成DISPATCH派发任务的方法,也就是mapDispatchToProps这种格式

 *   2. REACT-REDUX帮我们做了一件非常重要的事情:以前我们需要自己基于SUBSCRIBE向事件池追加方法,以达到容器状态信息改变,执行我们追加的方法,重新渲染组件的目的,但是现在不用了,REACT-REDUX帮我们做了这件事:“所有用到REDUX容器状态信息的组件,都会向事件池中追加一个方法,当状态信息改变,通知方法执行,把最新的状态信息作为属性传递给组件,组件的属性值改变了,组件也会重新渲染”

 REDUX原理之CREATE-STORE

/*
 * createStore:创建REDUX容器的
 *   @PARAMS
 *     reducer:函数
 *   @RETURN
 *     store : {
 *         getState,
 *         dispatch,
 *         subscribe
 *     }
 */
function createStore(reducer) {
    //=>创建一个STORE,STATE用来存储管理的状态信息,LISTEN-ARY用来存储事件池中的方法
    //=>STATE不用设置初始值,因为第一次DISPATCH执行REDUCER,STATE没有值,走的是
    //=>REDUCER中赋值的默认值信息,我们自己会在创建容器的时候就把DISPATCH执行一次!
    let state,
        listenAry = [];

    //=>DISPATCH:基于DISPATCH实现任务派发
    function dispatch(action) {
        //1.执行REDUCER,修改容器中的状态信息(接收REDUCER的返回值,把返回的信息替换原有的STATE),值得注意的是:我们是把返回值全部替换STATE,所有要求REDUCER中在修改状态之前,要先把原始的状态信息克隆一份,在进行单个的属性修改
        state = reducer(state, action);

        //2.容器中状态信息经过REDUCER修改后,通知事件池中的方法依次执行
        for (let i = 0; i < listenAry.length; i++) {
            let item = listenAry[i];
            if (typeof item === 'function') {
                item();
            } else {
                listenAry.splice(i, 1);
                i--;
            }
        }
    }

    dispatch({type: '$$INIT_DEFAULT_STATE'});//=>创建容器的时候执行一次DISPATCH,目的是把REDUCER中的默认状态信息赋值给REDUX容器中的状态

    //=>GET-STATE:获取容器中的状态信息
    function getState() {
        //1.我们需要保证返回的状态信息不能和容器中的STATE是同一个堆内存(否则外面获取状态信息后,直接就可以修改容器中的状态了,这不符合DISPATCH->REDUCER才能改状态的规范)
        /*//[浅克隆]
        AAAFFF111:{vote:BBBFFF111}
        {...state} => AAAFFF222:{vote:BBBFFF111}*/
        return JSON.parse(JSON.stringify(state));//=>深度克隆对象
    }

    //=>SUBSCRIBE:向事件池中追加方法
    function subscribe(fn) {
        //1.向容器中追加方法(重复验证)
        let isExit = listenAry.includes(fn);
        !isExit ? listenAry.push(fn) : null;

        //2.返回一个方法:执行返回的方法会把当前绑定的方法在事件池中移除掉
        return function unsubscribe() {
            let index = listenAry.indexOf(fn);
            // listenAry.splice(index, 1);//=>可能会引发数组塌陷
            listenAry[index] = null;
        }
    }

    return {
        dispatch,
        getState,
        subscribe
    };
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值