前言
如果你是像我这样的开发人员,那么在连接断开的抽象代码段时会遇到问题,并且很难理解状态的更新方式和位置。然后,你可能还达到了靠人脑记忆这些工作的极限。
我想我已经找到了解决方案,可以在不损失任何收益的情况下摆脱 Reducers。 在过去的10个月中,我构建了一个有效的状态管理器,称为ActiveJS,它不使用 reducer。
与其通过分发 action 让 reducer 隐式地发挥其魔力,不如说像纯函数那样调度 reducer 并摆脱该过程中的action。一石二鸟。
这些纯函数称为 producers,因为它们采用当前状态并产生新状态。
因此,reducers 减少了,producers 产生了,但是本质上他们在做同样的事情,更新了状态。听起来不错吧?
让我们对理论进行测试,并编写一些代码:
使用 Reducers 管理状态
首先,让我们看一下旧的 reducers。 这就是使用 reducers 的 Redux 实现的简单计数器的代码。
const counter = (state, action) => {
if (typeof state === 'undefined') {
return 0
}
// these are our reducers
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
// initialize the store and bind the reducers
const store = Redux.createStore(counter)
// subscribe for the state changes and log it to console
store.subscribe(() => console.log(store.getState()));
// logs 0 immediately and will log any future values
// dispatch the action for increment
store.dispatch({ type: 'INCREMENT' }) // makes the count 1
// dispatch the action for decrement
store.dispatch({ type: 'DECREMENT' }) // makes the count 0
复制代码
现在,让我们看看用 producers 替换 reducers 时会发生什么。
使用 Producers 管理状态
为此,我们将使用 ActiveJS,它是状态管理界的新成员,它具有称为单元(Units)的内置响应式数据结构,该结构用于存储并提供本地数据结构作为值,例如 number,string,array 等。 这些单元之一的 NumUnit,它存储一个数字值并确保它保持number,不允许使用 NaN。
我们将使用 NumUnit 来实现我们的计数器,因为我们希望计数始终是一个 number。
// initialize a reactive data structure to store numbers
const counter = new NumUnit() // with default initial-value 0
// two producers, pure-functions to produce an appropriate new value
const increment = value => value + 1
const decrement = value => value - 1
// subscribe for reactive value access, and log the value
counter.subscribe(value => console.log(value))
// immediately logs 0, and will log any future values
// dispatch the "increment" producer for increment
counter.dispatch(increment); // you'll see 1 in the console
// the pure function is called with the current value and
// the returned value is dispatched automatically
// dispatch the "decrement" producer for decrement
counter.dispatch(decrement); // you'll see 0 in the console
复制代码
看到没,么有 Reducers !
容易吧? 理论证明,代码仍然可以正常运行,易于测试,并且代码流没有中断。
但是 producers 只是 Units 的优点之一,其中包含了许多功能。
以下是一些与我们的“计数器”相关的功能:
直接分发
如果您不需要使用 producers,则可以直接分发新值。
counter.dispatch(2) // works
counter.dispatch(3) // works
复制代码
直接访问 Value
如果你不是被动地做某事,而只需要该值,则可以直接访问它。
// static value access
counter.value() // returns the current value immediately
复制代码
防止无效的数据类型
为此,我们无需执行任何操作,NumUnit 会负责。它仅接受一个数字,从而确保始终提供一个数字值。节省你进行任何完整性检查的需要。
counter.dispatch('an evil string') // won't work
counter.dispatch({nein: 'nein nein'}) // won't work
counter.dispatch(NaN) // won't work
counter.dispatch(() => NaN) // won't work
counter.dispatch(['what', 'about', 'this']) // won't work
复制代码
防止重复分发
防止重复值就像提供配置选项一样容易。
const counter = new NumUnit({distinctDispatch: true})
// that's it, done
counter.dispatch(2) // works
counter.dispatch(2) // won't work, it'll get ignored
counter.dispatch(3) // works
counter.dispatch(3) // won't work, it'll get ignored
复制代码
防止负数
我们的计数器应仅具有正值,这样才合理。并且通过提供一个函数来确保这一点也很容易,Unit 将调用它来检查是否应该更新新值。
const counter = new NumUnit({
// If it returns a falsy value for a dispatch, that dispatch is ignored.
// So just return true if the newly dispatched value is positive.
customDistinctDispatch: (prev, newValue) => newValue >= 0
})
// that's it, done
counter.dispatch(2) // works
counter.dispatch(-2) // won't work, it'll get ignored
counter.dispatch(3) // works
counter.dispatch(-3) // won't work, it'll get ignored
复制代码
就是这样,朋友们。 如果你想自己尝试一下,点击这里。 仅 NumUnit 和整个 Units 可以做的甚至更多。 这是一篇展示这些功能的文章。
原文地址: dev.to/dabalyan/st…