非事件驱动的Redux

如果前端的通量核心概念错了怎么办?

NeONBRAND摄Unsplash

第一次听说Flux可能使您感到困惑。 回顾过去,如此简单的事情竟然让我掌握了如此多的文章和教程,这真是令人惊讶。 我非常感谢Redux是Flux最受欢迎的衍生产品之一,因为它确实是Flux核心方面的一种非常简单的表示方式-单向数据流,涉及调度将商店更改为改变看法。

这些动作是包含新数据和标识类型属性的简单对象。 — https://facebook.github.io/flux/docs/in-depth-overview.html#content

Facebook给出了操作的特定定义,即具有某些属性的纯JavaScript对象。 尽管Facebook从未明确将动作更改商店的过程描述为事件驱动的体系结构,但是使用普通的javascript对象更改商店时,很难想象有其他任何设计模式。

事件驱动架构通常会看到一些关键模式。 事件源和事件通知是Martin Fowler 在其博客中谈到的两个问题。 事件源是关于存储一系列事件的,以便可以用来重建系统状态。 事件通知是关于从系统中调度动作的,该系统与谁消耗这些动作无关。 事件通知的优点之一是它提供的去耦。 发出一个事件,任何进程都可以使用该事件,而无需知道还有谁在使用该事件。 我认为Flux肯定会展示事件源和事件通知,但是后者的质量可能会带来问题。

事件通知的问题之一是可能很难跟踪事件流到事件处理程序,因为该流是隐式的而不是显式的。 一旦事件被发出(或调度了一个动作),它就会进入一种黑匣子,该黑匣子返回更改后的状态。 在Redux世界中,已经尝试采用某些标准来使这些关系更明确( 例如,鸭子 ),但是真正的问题是为什么有必要使这种关系更明确? 使用事件通知应该是一个可以接受的折衷方案,但是相反,感觉像是一个折衷方案,没人真正理解为什么他们必须首先进行。

我认为Flux的部分问题在于Facebook出于其自身的应用程序开发了它。 Facebook的应用程序非常复杂,我猜这些应用程序的前端组件是如此复杂,以至于它们实际上需要多个团队来监督特定的领域。 我认为Flux对于这种情况很有意义,但是就我个人而言,我从未参与过任何需要多个前端团队的项目。 我不是在说由3或4个人组成的小组一起完成前端的某些方面,而是在谈论由15个以上的开发人员组成的专门部门,这些部门很少甚至看不到任何重叠的工作。

通量对于Facebook来说甚至不理想。 我们知道他们在开源技术之前就采用了Graphql,如果他们使用Relay或同等的库来管理状态,那么他们实际上并没有使用Flux。 是的,Relay受到Flux的启发,但是在Relay中分派动作的过程是如此深层,以至于只有在使用调试工具时才可见。 想一想,Relay可能甚至没有调度动作。 从官方中继文档“ commitUpdate类似于在Flux中分派动作”,但是为什么它类似于而不是简单地分派动作?

Flux和事件通知的真正问题是前端耦合的问题。 我们听到了很多关于微服务的信息,以及在较小程度上扩展了无服务器功能,但是前端没有等效的概念。 关于前端的某些事情使得几乎不可能分离成更小的包装。 也许是因为前端是所有事物融合在一起的地方。 也许是因为在整个应用程序中,前端的经验应该具有凝聚力。 不管是什么,前端都很难分离成较小的组件,因此,当我们不可知地从一个系统发出事件时,我们实际上只是在向自己发出事件。

丹·阿布拉莫夫(Dan Abramov )谈到了Redux局限性,以及它并非适用于每个项目。 Redux并不完美,但可以很好地实现其目的。 两年前,它在风暴中席卷了世界,除了Relay,它是React最普遍的状态管理工具。 也许是时候采用另一种方法了。 也许是非事件驱动的Redux方法。

import {createStore} from 'noredux'
const initialState = 1
const store = createStore(initialState)
const reducer = (state)=>state + 1
store.dispatch(reducer)
console.log(store.getState())
// 2

不仅Redux(noredux)是一个采用不同方法来诱发状态更改的库。 您无需分派动作,而是分派减速器。 这是状态更改的显式方法。

但是不要被愚弄,这种方法有其自身的局限性。 以类似于传统Redux的CombineReducers的方式实现关注点分离并不容易。

import {scopeReducer} from 'noredux'
const pretodosReducerCreator = () => state => state + 1
const selector = state => state.todos
const setter = (state, result)=>({...state, todos: result})
const todosReducerCreator = scopeReducer(selector, setter, pretodosReducer)

要么

import {defaultScopeReducer} from 'noredux'
const pretodosReducerCreator = () => state => state + 1
const todosReducer = defaultScopeReducer('todos', pretodosReducerCreator)

我个人认为,图书馆背后的思想比图书馆本身更重要。 使Redux更明确。 对于希望试用Noredux的任何人,您都可以在noredux github repo中看到一个示例。 如果您决定尝试使用Noredux,目前尚没有太多基础架构,因此您将无法使用chrome redux devtools或react-router-redux(但是react-redux与noredux可以很好地工作) 。

话虽如此,我创建了一个redux-noredux包,以便您可以在redux项目中使用Noredux,并且在github存储库中有一个示例应用程序来演示其用法。 目前,这是Noredux的首选实现。

import {createStore} from 'redux'
import {noreduxAction, enableNoredux} from 'redux-noredux'
import reducers from './reducers'
const store = createStore(enableNoredux(reducers), {todos: 0})
const noreduxReducer = (state)=>({...state, todos: state.todos + 1})
noreduxReducer.type = 'exampleType'
noreduxReducer.args = []
store.dispatch(noreduxAction(noreduxReducer))
/*
{
type: '@@redux-noredux/exampleType'
args: [],
reducer: noreduxReducer,
noredux: true,
}
*/

如果您使用redux的CombineReducers,则此方法会有一些警告。 CombineReducers不允许未附加化简器的状态属性,因此您需要伪造它。

import {combineReducers} from 'redux'
import {fakeReducer} from 'redux-noredux'
import soonToBeDones from './soonToBeDones'
import {initialState as todosInitialState} from './todos'
export default combineReducers({
soonToBeDones,
todos: fakeReducer(todosInitialState)
})

干杯。

From: https://hackernoon.com/non-event-driven-redux-5ce56776184f

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值