没有 Reducers 的状态管理

·  阅读 404

前言

如果你是像我这样的开发人员,那么在连接断开的抽象代码段时会遇到问题,并且很难理解状态的更新方式和位置。然后,你可能还达到了靠人脑记忆这些工作的极限。

我想我已经找到了解决方案,可以在不损失任何收益的情况下摆脱 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…

分类:
前端
标签:
分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改