实现MyRedux系列
现在通过前边两部分,我们实现了一个通用的createStore:
function createStore (state, stateChanger) {
const listeners = []
const subscribe = (listener) => listeners.push(listener)
const getState = () => state
const dispatch = (action) => {
state = stateChanger(state, action) // 覆盖原对象
listeners.forEach((listener) => listener())
}
return { getState, dispatch, subscribe }
}
那他怎么用呢?
let appState = {
title: {
text: 'React.js',
color: 'red',
},
content: {
text: 'React.js 内容',
color: 'blue'
}
}
function stateChanger (state, action) {
switch (action.type) {
case 'UPDATE_TITLE_TEXT':
return {
...state,
title: {
...state.title,
text: action.text
}
}
case 'UPDATE_TITLE_COLOR':
return {
...state,
title: {
...state.title,
color: action.color
}
}
default:
return state
}
}
const store = createStore(appState, stateChanger)
...
其实可以优化一下,appStore和stateChange可以合并
function stateChanger (state, action) {
if (!state) {
return {
title: {
text: 'React.js',
color: 'red',
},
content: {
text: 'React.js 内容',
color: 'blue'
}
}
}
switch (action.type) {
case 'UPDATE_TITLE_TEXT':
return {
...state,
title: {
...state.title,
text: action.text
}
}
case 'UPDATE_TITLE_COLOR':
return {
...state,
title: {
...state.title,
color: action.color
}
}
default:
return state
}
}
stateChange现在既充当了获取初始化数据的功能,也充当了生成更新数据的功能,如果传入了state就更新数据,否则为初始化数据,那createStore可以优化成一个参数,因为state和stateChange可以合并
function createStore (stateChanger) {
let state = null
const listeners = []
const subscribe = (listener) => listeners.push(listener)
const getState = () => state
const dispatch = (action) => {
state = stateChanger(state, action)
listeners.forEach((listener) => listener())
}
dispatch({}) // 初始化 state
return { getState, dispatch, subscribe }
}
createStore 内部的 state 不再通过参数传入,而是一个局部变量 let state = null。createStore 的最后会手动调用一次 dispatch({}),dispatch 内部会调用 stateChanger,这时候的 state 是 null,所以这次的 dispatch 其实就是初始化数据了。createStore 内部第一次的 dispatch 导致 state 初始化完成,后续外部的 dispatch 就是修改数据的行为了。
stateChange可以换一个名字,就叫他reducer,不要问,问就是reducer
function createStore (reducer) {
let state = null
const listeners = []
const subscribe = (listener) => listeners.push(listener)
const getState = () => state
const dispatch = (action) => {
state = reducer(state, action)
listeners.forEach((listener) => listener())
}
dispatch({}) // 初始化 state
return { getState, dispatch, subscribe }
}
reducer
createStore接受一个叫reducer的函数,他一定是一个纯函数,他接收两个参数,一个是state,一个是action
他不能干任何事情,只能初始化和计算新的state
总结
从第一篇开始,首先发现如果共享的状态能被随意修改,那程序地行为会不可预料,所以我们要求只能通过dispatch去进行数据修改,而且必须要在action中声明,然后我们把它抽象出来成为一个createStore,它能生产store,里面有getState和dispatch让我们使用
后来发现每次修改数据都要重新渲染,而我们希望能够自动渲染视图,所以使用了订阅者模式,通过store.subscribe订阅数据修改事件,为了让它自动渲染视图
在我们使用的时候发现每次都重新渲染视图会有很大的性能问题,所以使用共享结构的对象来解决问题,而后让stateChanger更名为reducer,并让他是一个纯函数,负责初始化state,根据state和action计算具有共享结构的新state

来源:CSDN
作者:moe_王
链接:https://blog.csdn.net/qq_40766509/article/details/104439810