更好用的Redux

81 阅读1分钟

大型项目中往往会有一份独立于业务的数据管理模块,这个数据可用于整个项目, 也可以在项目中分模块使用,接下来我们手写一份数据管理工具。

首先我们需要使用数据, 并改变数据:

import { broadcast, subscribe } from './utils'

function createStore (initData, reducer) {
    // 传入的初始化的数据 Object类型
    const state = initData
    const useStore = () => {
        // 收集依赖
        ......
        return state
    }
    const dispatch = () => {
        // 更新数据
        ......
        // 通知渲染组件
        ......
    }
    return { useStore, dispatch }
}

创建store的作用只有两个, 返回我们所需要的数据(useStore),更新数据(dispatch) 

import { broadcast, subscribe, unSubscribe } from './utils'

function createStore (initData, reducer) {    // 传入的初始化的数据 Object类型
    const state = initData
   // 模块名
   const nameSpace = state.nameSpace    const useStore = (nameSpace = nameSpace) => {
        // setState的作用是触发渲染
        const [, setState] = useState()
        // 收集依赖
        useEffect(() => {
            subscribe(nameSpace, setState)
            return () => unSubscribe(nameSpace, setState)
        }, [nameSpace])
        return state
    }
    const dispatch = (data) => {
        // 比较数据
        const isDiff = compareData(data, state)
        if (isDiff) {
            // 更新数据
            updateData()
            // 通知渲染组件也是就是render
            broadcast()
        }
    }
    return { useStore, dispatch }
}

对比数据:

function compareData (data, state) {
    // 把所有值转换成基础类型的值, 因为其中有可能是函数
    transFormData(data)
    // 比较值是否存在不同
    diffData
}

dispatch({
    name: 'Claire',
    age: () => { return '30' }
})

因为要兼容上面两种使用方法, 需要转换一下,把函数执行一下取出其中的值

function transformData (data) {
    const tempPromises = []
    const tempObj = {}
    if (Object.keys(data).every((key) => {
        const isFunc = Object.prototype.toString().call(data[key]) === '[Object Function]'        if (ifFunc) tempPromises.push(tempObj[key] = Promise.resolve(data[key]()))
        return !isFunc
    })) {
        return data
    } else {
        await Promise.all(tempPromises).then(res => {
            Object.keys(tempObj).forEach((key, index) => {
                data[key] = res[index]
            })
        })
        return data
    }
}

对比

const diffData = (oldVal, val) => {    if (valueType(oldVal) !== valueType(val)) return true    if (val && typeof val === 'object') {        try {            return JSON.stringify(oldVal) !== JSON.stringify(val)        } catch (e) {            return true        }    }    return !Object.is(oldVal, val)}

更新数据:

function updateData () {
    return {...state, ...data}
}