按照redux源码仿写一个前端状态管理框架XRedux

文章介绍了XRedux,这是一个根据Redux仿写的状态管理框架,已实现主要API,包括createStore、getState、subscribe和dispatch。文中逐步展示了如何实现这些功能,从创建store到处理action和更新状态,并在最后初始化默认的store数据。
摘要由CSDN通过智能技术生成

前端状态管理框架XRedux是依据前端状态管理框架redux仿写的,目前只实现了主要的API,后续会添加其他API的实现。

XRedux仓库地址如下:
gitee仓库
github仓库

一、redux主要API

createStore:根据reducer插件store上下文

getState:获取状态数据

subscribe:监听依赖

dispatch:分发action,触发状态数据更新,从而触发依赖更新

二、XRedux代码实现

1、依葫芦画瓢,先实现大概函数结构

const createStore = (reducer) => {
    if(typeof reducer !== 'function') {
        throw new Error('reducer must be an function.')
    }

    const getState = () => {
    
    }

    const subscribe = (listener) => {
        
    }

    const dispatch = (action) => {
        
    }

    return {
        getState,
        subscribe,
        dispatch,
    }
}

export { 
    createStore 
}

2、先实现getState函数

const createStore = (reducer) => {
    if(typeof reducer !== 'function') {
        throw new Error('reducer must be an function.')
    }

    let state

    const getState = () => {
        return state
    }
    
    return {
        getState,
        subscribe,
        dispatch,
    }
}

export { 
    createStore 
}

3、实现subscribe

const createStore = (reducer) => {
    if(typeof reducer !== 'function') {
        throw new Error('reducer must be an function.')
    }

    let state
    let listeners = []

    const getState = () => {
        return state
    }

    const subscribe = (listener) => {
        if(typeof listener !== 'function') {
            throw new Error('listener must be an function')
        }
        if(!listeners.includes(listener)) {
            listeners.push(listener)
        }
        return () => {
            let index = listeners.indexOf(listener)
            listeners.splice(index, 1)
        }
    }

    return {
        getState,
        subscribe,
        dispatch,
    }
}

export { 
    createStore 
}

4、实现dispatch

const createStore = (reducer) => {
    if(typeof reducer !== 'function') {
        throw new Error('reducer must be an function.')
    }

    let state
    let listeners = []

    const getState = () => {
        return state
    }

    const subscribe = (listener) => {
        if(typeof listener !== 'function') {
            throw new Error('listener must be an function')
        }
        if(!listeners.includes(listener)) {
            listeners.push(listener)
        }
        return () => {
            let index = listeners.indexOf(listener)
            listeners.splice(index, 1)
        }
    }

    const dispatch = (action) => {
        if(!isPlainObject(action)) {
            throw new Error('action must be plain object.')
        }
        if(typeof action.type === 'undefined') {
            throw new Error("action must have the property 'type'")
        }
        state = reducer(state, action)
        listeners.forEach(listener => {
            listener()
        })
        return action
    }

    return {
        getState,
        subscribe,
        dispatch,
    }
}

export { 
    createStore 
}

5、初始化默认的store数据

需找一个与业务逻辑冲突很小的一个随机字符串,所以这里采用了redux项目原来的随机字符串规则。

const isPlainObject = (data) => {
    return Object.prototype.toString.call(data) === '[object Object]'
}

const createStore = (reducer) => {
    if(typeof reducer !== 'function') {
        throw new Error('reducer must be an function.')
    }

    let state
    let listeners = []

    const getState = () => {
        return state
    }

    const subscribe = (listener) => {
        if(typeof listener !== 'function') {
            throw new Error('listener must be an function')
        }
        if(!listeners.includes(listener)) {
            listeners.push(listener)
        }
        return () => {
            let index = listeners.indexOf(listener)
            listeners.splice(index, 1)
        }
    }

    const dispatch = (action) => {
        if(!isPlainObject(action)) {
            throw new Error('action must be plain object.')
        }
        if(typeof action.type === 'undefined') {
            throw new Error("action must have the property 'type'")
        }
        state = reducer(state, action)
        listeners.forEach(listener => {
            listener()
        })
        return action
    }

    const randomStr = () => Math.random().toString(36).substring(7).split('').join('.')

    dispatch({
        type: '@@XRedux/INIT' + randomStr()
    })

    return {
        getState,
        subscribe,
        dispatch,
    }
}

export {
    createStore 
}

上面也是完整代码逻辑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值