Open libin1991 opened 6 years ago
redux状态管理器,实质上就是一个单例模式。我们来实现一个简单的redux模型,实现之前我们要先熟悉它的用法。
下面我们按照这个思想来想想怎么做。 我们来抽象一下,提取出最核心的思想,动用鬼斧神工画个图:
用文字来描述一下,一个唯一的仓库里,有一个私有属性state,仓库由门卫大哥进行管理,所有对state的操作都要经过门卫大哥,外面的人无权直接对state进行操作,如果有进行订阅,则在状态改变后收到状态改变事件。好了,我们按照这个思想来开始code吧
const state={ a: 1 }
function createStore(){ const state={ a: 1 } }
function createStore() { let state={ a:1 }; function getState() { return state //此处直接将state返回,会使state引用地址暴露,从而被引用对象改变值 } return { getState } } let store = createStore() // 创建一个仓库 let state = store.getState() // 获取状态state console.log(store.getState()) // 输出{ a: 1 } state.a = 2 //将state a的值设置为2 console.log(state) // 输出为{ a: 2 } console.log(store.getState()) // 此时仓库中state的值也改变了,输出为{ a: 2 }
所以我们将第六行 return state 替换为 return JSON.parse(JSON.stringify(state)) 可以避免这个问题。
return state
return JSON.parse(JSON.stringify(state))
'use strict' function createStore() { let state; function getState() { return JSON.parse(JSON.stringify(state)) } function dispatch(action) { // 分发 state = reducer(state,action) // 接收当前 State 和Action作为参数,返回一个新的 State } dispatch({ type: '@@INIT' }) // 在创建仓库的时候,初始化state的值 return { getState, dispatch } } let initState = { count: 0 } //处理器,接收二个参数 ,接收老状态和action,返回新状态 function reducer(state = initState, action) { // 如果state没有值,默认值为initState //判断动作的类型 switch (action.type) { case 'ADD_TODO': return { ...state, count: action.number }; //...state解构state所有属性,count: action.number覆盖前面的值 default: return state; } } let store = createStore() // 创建一个仓库 let state = store.getState() // 获取状态state let action = { type: 'ADD_TODO', number: 1 }; store.dispatch(action); // 派发一个action,改变state的状态 console.log(store.getState()) // 输出{ count: 1 }
diapatch中执行我们定义的reducer处理器函数,增删改查。例子演示了先创建一个仓库,在创建新仓库的时候初始化了state。然后diapatch一个action:ADD_TODO,执行的处理是改变count的值,返回一个新的state对象,最后我们可以看到输出,原来的state在初始化后变成{ count: 0 },又在ADD_TODO后变成了{ count: 1 }。
reducer函数是我们在使用redux时需要自己定义的处理函数。
至此,我们已经实现了创建一个仓库,并且可以自定义一些处理函数对state进行操作。还缺了什么呢?在实际项目中,状态改变后我们的大部分的组件需要立即得到新的状态,然后根据状态改变作出不同的处理。也就是说组件对state进行一个监听,一旦state发生改变,立马通知到对应的组件。让我们来继续实现吧。。。
function createStore() { let state; let listeners = []; function getState() { return JSON.parse(JSON.stringify(state)) } function dispatch(action) { // 分发 state = reducer(state,action); // 接收当前 State 和Action作为参数,返回一个新的 State listeners.forEach(listener => listener()) // 一旦状态改变,触发所有的监听函数,这里需要优化,只有相关状态改变才需要触发 } function subscribe(listener){ // 订阅,如果需监听状态变化,将监听函数传过来 listeners.push(listener); // 保存监听函数到监听数组 return function () { // 返回取消订阅的函数 listeners = listeners.filter(item => item != listener); // 过滤监听函数 } } dispatch({ type: '@@INIT' }); // 在创建仓库的时候,初始化state的值 return { getState, dispatch, subscribe } } /*这里是分割线,上面一部分是仓库定义,下面部分是使用方法*/ let initState = { count: 0 } //处理器,接收二个参数 ,接收老状态和action,返回新状态 function reducer(state = initState, action) { // 如果state没有值,默认值为initState //判断动作的类型 switch (action.type) { case 'ADD_TODO': return { ...state, count: action.number }; //...state解构state所有属性,count: action.number覆盖前面的值 default: return state; } } let store = createStore() // 创建一个仓库 let action = { // 定义一个action type: 'ADD_TODO', number: 1 }; let unADD = store.subscribe(function(){ // 监听状态改变 console.log('状态改变了,现在的state为:') // 状态改变了,现在的state为: console.log(store.getState()) // { count: 1 } }) store.dispatch(action); // 派发一个action,改变state的状态 复制代码
铛铛铛~,我们的redux基本模型就做好了,有什么不懂的可以提问哟~
redux状态管理器,实质上就是一个单例模式。我们来实现一个简单的redux模型,实现之前我们要先熟悉它的用法。
下面我们按照这个思想来想想怎么做。 我们来抽象一下,提取出最核心的思想,动用鬼斧神工画个图:
用文字来描述一下,一个唯一的仓库里,有一个私有属性state,仓库由门卫大哥进行管理,所有对state的操作都要经过门卫大哥,外面的人无权直接对state进行操作,如果有进行订阅,则在状态改变后收到状态改变事件。好了,我们按照这个思想来开始code吧
第一步:声明一个对象
第二步:将对象包裹起来,使其不可随意访问
第三步:暴露出一个方法,使外部可以对状态进行操作
所以我们将第六行
return state
替换为return JSON.parse(JSON.stringify(state))
可以避免这个问题。第四步:除了获取状态我们还需要操作状态,暴露第二个方法,dispatch,顺便将state的初始化进行一下优化
diapatch中执行我们定义的reducer处理器函数,增删改查。例子演示了先创建一个仓库,在创建新仓库的时候初始化了state。然后diapatch一个action:ADD_TODO,执行的处理是改变count的值,返回一个新的state对象,最后我们可以看到输出,原来的state在初始化后变成{ count: 0 },又在ADD_TODO后变成了{ count: 1 }。
reducer函数是我们在使用redux时需要自己定义的处理函数。
至此,我们已经实现了创建一个仓库,并且可以自定义一些处理函数对state进行操作。还缺了什么呢?在实际项目中,状态改变后我们的大部分的组件需要立即得到新的状态,然后根据状态改变作出不同的处理。也就是说组件对state进行一个监听,一旦state发生改变,立马通知到对应的组件。让我们来继续实现吧。。。
第五步:增加一个订阅功能subscribe
铛铛铛~,我们的redux基本模型就做好了,有什么不懂的可以提问哟~