• Redux的createStore实现


    Redux的createStore实现

      使用过react的同学应该对Redux这个东西有所了解。他是一种全局状态管理的思想(对, 这里我觉得它是一种思想, 因为对于React来说, 其实Redux内部并没有什么需要与React兼容的东西, react-redux 库里才有), 它信奉的是:

    • 唯一数据仓库
    • 只能读取
    • 数据改变只能通过纯函数进行

      这其实对我们是一种约束, 毕竟我们就算引入了Redux, 也能使用this.props去进行父子组件数据传输, 但是当你需要非父子组件的通信的时候, 里面的数据流动会非常难以捉摸, 所以我们使用Redux。

    在React中集成Redux时, 在程序的入口处,我们可以看到这样的一段代码

    // 这里的todoApp是一个Reducer函数,接受的是state和actions
    const store = createStore(todoApp)
    

      在我们的react使用单一仓库的时候,能看到一下的一些类似的代码,从中我们能看到,我们本组件的state是通过this.state = store.getState()所创建的, 那么我们的store是一个对象,里面有一个getState函数能够返回内部的state,同时这个state是需要持久保存的,所以我们大概能有一些思路。

    import React, { Component } from 'react'
    import store from '../../store'
    import { getIPData } from '../../store/actionCreators'
    
    class Page extends Component {
        // 我的初始化的一个组件,已经能够使用Redux了
        constructor(props) {
            super(props);
            this.state = store.getState()
            store.subscribe(this.storeChange.bind(this));
        }
    
        componentWillMount() {
            // 获取IP数据,这里是作为一个dispatch的例子
            // 值得注意的是getIPData()返回的是一个带type字段的一个对象。
            const action = getIPData();
            store.dispatch(action);
        }
    
        render() {
            return (
                <div className="page">
                </div>
            )
        }
    
        storeChange() {
            this.setState(store.getState())
        }
    }
    export default Page
    

      接下来我将自己写的createStore函数贴出来, 然后讲解。这个函数实现了大部分功能,但是对于中间件的处理这里并没有能够实现,后面我应该会对其有一些补充。

    
    export default function createStore(reducer){
        let state = null;
        const listeners = [];
        const getState = () => state
        
        const dispatch = (action) => {
            state = reducer(state, action)
            listeners.forEach(listener => listener())
        }
        
        const subscribe = (listener) => listeners.push(listener)
        
        // 这里初始化dispatch的原因是在这之前,state是为null的
        //所以我需要传一个不存在的action去reducer里面,拿到最默认的那个defaultState
        //这个defaultState写在reducer的那个文件里面
        dispatch({});
        return {
            dispatch,
            subscribe,
            getState,
        }
    }
    

      所以刚才的分析, 我们需要创建一个函数对象createStore

      1、createStore里面用闭包的方法储存了一个state,我们程序用到的仓库就是这个、还储存有一个函数数组listeners,用于储存用户定义的函数(一般是用更新后的仓库重置this.state),因为我其实有多个页面都注册了一个订阅函数, 所以使用函数数组, 当需要分发时取出来取出来调用即可。

      2、createStore需要定义一个方法getState能够拿到state,这样就能够在React中使用this.state = store.getState()来初始化state并进行读取了

      3、createStore还需要定义一个方法dispatch, 因为redux不能直接修改state的值, 所以必须通过dispatch函数,传入action, 然后带着state直接传入reducer里, reducer会传回修改后的state

      4、createStore再需要定义一个方法subscribe, 这是用来监听修改的函数, 在使用时, 绑定一个函数, 这个函数里会在外界获得state。所以这个函数应该接收一个函数, 然后push入一个队列里, 可是应该实时监听的, 为何要置入队列呢?这里我的理解是, 在一开始就将"外界重新获得state"这个函数置入队列, 类似Promise我承诺会使用这个函数。所以这个函数的使用应该放置在dispatch里面, 它传回一个state后, 做的事情是将所有队列中的"外界重新获得state"函数全部拿出来执行一遍。

      所以这个createStore函数的效果很明显了,getState用于获取当前state, subscribe用于给外界设置监听并将监听函数储存在createStore函数的属性中, 每次用户通过dispatchaction来修改state的时候, 将里面所有的监听函数拿出来执行一遍。而dispatch则是用来执行state修改的, 毕竟这个函数不允许使用setState这类的函数。

      这样, 我们就简单了解并分析了Redux的基本原理并对其进行了重写, 就像我提到的, Redux其实是一种约束的思想而出现, 这意味着在node中, 我们同样也能使用Redux(虽然我觉得可能没有必要)

  • 相关阅读:
    axis2 WebService 请求参数xml格式
    钉钉扫码登录第三方,appSecret签名算法(附包名)
    win10 IE浏览器中,设置指定程序查看源文件,设置查看源默认程序
    myeclipse CI 2018.8.0和 myeclipse 10 禁止空格自动上屏,自动补全插件
    开发必备网站记录
    二叉树的前序中序后序遍历(简洁)
    贪心算法入门
    Java-二分查找与二叉树关系详解-2021-7-20
    Visual Studio Code快速创建模板(html等)
    java 面向对象1之继承
  • 原文地址:https://www.cnblogs.com/JobsOfferings/p/Redux_createStore.html
Copyright © 2020-2023  润新知