Redux的createStore实现

Posted jobsofferings

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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(虽然我觉得可能没有必要)

以上是关于Redux的createStore实现的主要内容,如果未能解决你的问题,请参考以下文章

redux之createStore方法底层封装模拟

混淆 createStore 在 redux 中的工作方式

Redux 中 combineReducers实现原理

redux教程之源码解析createStore

我可以在组件中使用redux中的createStore()吗?

redux中createStore方法的默认参数