Redux: 建议动作常量以过去时命名

创建于 2015-08-01  ·  55评论  ·  资料来源: reduxjs/redux

由于#377 已关闭(出于有效的生态系统原因),如何在文档中建议写 COUNT_INCREASED 而不是 INCREASE_COUNT?

这样一来,人们就不太愿意将副作用放在减速器中。

最有用的评论

我不相信(还),但愿意相信。
对我来说 Actions 是一个意图,reducer 可能会选择不增加,所以 COUNT_INCREASED 感觉有点奇怪。
另外 { type: 'COUNT_INCREASED', data: 2 } 与 { type: 'INCREASE_COUNT', data: 2 } (“增加 2”)具有完全不同的含义(“增加到 2”)。

所有55条评论

这对我来说听起来很明智!

我同意:+1:

我不相信(还),但愿意相信。
对我来说 Actions 是一个意图,reducer 可能会选择不增加,所以 COUNT_INCREASED 感觉有点奇怪。
另外 { type: 'COUNT_INCREASED', data: 2 } 与 { type: 'INCREASE_COUNT', data: 2 } (“增加 2”)具有完全不同的含义(“增加到 2”)。

在 BUTTON_PUSHED 的情况下,这是有道理的 - 但我不同意 INCREASE_COUNT 应该变成 COUNT_INCREASED - 当 AC 创建该操作时,计数不会增加。

我并没有立即被说服。 我得考虑一下这个主意。

实际上,在这种情况下,全名将是 COUNT_INCREASE_REQUESTED,
这确实有点长,但仍然传达了实际意图。

COUNT_INC_REQD?

在Sun,2015年8月2日,04:12奇尔麦欧[email protected]写道:

我并没有立即被说服。 我得考虑一下这个主意。


直接回复此邮件或在 GitHub 上查看
https://github.com/gaearon/redux/issues/384#issuecomment -126977702。

哇。
(在手机上输入,请原谅简洁)

我认为 ActionCreator 有义务检查一个动作是否
可能(通过 thunk),然后盲目地发送出去。

Reducers 有义务始终保持返回的状态有效。

动作日志是发生的事情的真相,状态只是一个
反映这一点。

2015 年 8 月 2 日星期日 07:07 Wout Mertens wout。 [email protected]写道:

实际上,在这种情况下,全名将是 COUNT_INCREASE_REQUESTED,
这确实有点长,但仍然传达了实际意图。

COUNT_INC_REQD?

在Sun,2015年8月2日,04:12奇尔麦欧[email protected]写道:

我并没有立即被说服。 我得考虑一下这个主意。


直接回复此邮件或在 GitHub 上查看
https://github.com/gaearon/redux/issues/384#issuecomment -126977702。

哇。
(在手机上输入,请原谅简洁)

哇。
(在手机上输入,请原谅简洁)

COUNT_INCREASED :-1: 原因已经在线程中说明
COUNT_INCREASE_REQUESTED :+1: 但它可能太冗长了

建议以“命令式”编写操作类型如何(如著名的 Chris Beams 的 Git 提交消息样式指南)。 所以在这种情况下INCREASE_COUNT工作得很好,因为它处于命令式的情绪中,即“写成好像在发出命令或指令”,并传达了这样一种观念,即创建一个动作只是表示某事应该发生的愿望或意图在某个时间点。

我倾向于将ActionTypes视为过去发生的事情。 通过将它与我已经有些熟悉的 ddd/cqrs/es 进行比较,我发现最初更容易理解通量。 @abdullin@fisherwebdev之间的讨论可能在这里很有趣。 特别是标题为“操作 - > 事件”的位

就个人而言,我得出的结论是,我们正在混合两种设计模式和两种模型来思考系统。 两者在分离时都是有效的,并且可能在某些应用中可以混合使用。

一种基于 EventSourcing,其中 Action 对象表示发生了什么。 Reducers 然后将过去解释为一种状态,不同的 reducer 可以将其解释为对过去的不同看法。

第二个基于write ahead log (WAL) 。 它用于解决各种难题,从从日志中恢复文件系统开始,数据库事务,复制,故障后在另一台机器上恢复......也称为日志,事务日志,命令日志......
在这种情况下,Action 对象主要代表改变状态的意图和任何需要的东西,fe TRANSACTION_BEGIN, TRANSACTION_COMMIT... WAL 在数据库中被大量用于改变状态。 各种分布式问题都基于它来解决。

我认为香草通量更像是 WAL。 我认为这两种方法都是有效的方法,它可能取决于应用程序类型,哪个更有意义。 可能 Redux 应该对他们保持不可知论。

我对过去时的问题是有时用过去时命名动作对象很棘手。 我对命令式情绪的问题是它绑定到 WAL 设计模式。 因此,我目前正在研究使用名词来描述我的动作对象的选项。 它们似乎适用于两种设计模式,并允许使用棘手的名称。 它们很相似,有时与命令式情绪相同,INCREASE_COUNT 更改为 COUNT_INCREASE,VISIT 为 VISIT 等。

我们可以以 DOM 事件为例。 尝试用过去时命名“mousemove”、“mouseup”、“mousedown”,我认为在您的域中找到相同的棘手操作不会花很长时间。 它允许“上下文菜单”等。

Redux 可以只描述所有方法的优缺点,让开发人员选择哪种模型适合他的应用程序并更好地思考。 我相信 Redux 可以是不可知的,并且可以轻松支持两者。

也许这两种设计模式都可以接受 - COMMENT_DELETE 或 COMMENT_DELETION,即 OBJECT_VERB 或 OBJECT_NOUN,因为 OBJECT_VERB 不被理解为命令式情绪,与 DELETE_COMMENT 相比并没有那么多。

这就是为什么在文档中同时包含两者可能会令人困惑的原因(虽然在分离技术上是正确的):

_改变状态的唯一方法是发出一个动作,一个描述发生了什么的对象。 (三原则)_

_一个动作是一个简单的对象,表示改变状态的意图。 (词汇​​表中的动作)_

@vladap我想我
我认为很明显,行动本身的定义很差,足以造成很多混乱。 我们现在对此缺乏语义。
行动 - 呼吁做某事或某事发生的事实?
这个问题的答案定义了减速器应该有多聪明。 这塑造了整个应用程序。
我认为有一些共同的共识,即应该丢弃减速器。 redux 的核心应该是简单、同步和可重载。 为了获得转储减速器,我们应该向他们传播诸如“要求做某事”而不是“事实”之类的动作。 因为事实可以有不同的解释,所以reducer 倾向于做出一些解释,这使它自动变得更聪明。 我更喜欢称之为“调用做某事”-指令(长名称不好,但我喜欢语义)。
我认为作为价值的指令和事实之间存在差距,但我们现在称它们为行动——这是混淆的主要来源。
正如@gaearon 所评论的那样
“有些“智能”动作在某些时候会变成“愚蠢”动作,它们经常描述“应该发生什么”中间件解释智能动作并将它们变成愚蠢的动作。”
过去时倾向于认为行动是事实,所以我认为这实际上是一个坏主意。 我相信减速机应该得到说明。 我想提到的另一件事是,这一切都与其他问题“业务逻辑应该存在于我的应用程序中的什么位置?”有关。 用户点击某处(事实),它被解释为指令数组。 (fact)=>(List[instructions]) - 这就是 actionCreator 现在实际做的。 我不清楚中间件如何与 actionCreator 相关联。 我认为中间件更底层,不应该做任何决定。 只是一些同构的东西,比如拆箱 promise 和 thunk。 PS 也许意图更好,因为它像@ioss所说的那样更短,但指令在语义上也更好。

我喜欢使用名词的想法! 这 - 除了易于命名 - 使它们成为永恒,它们同时是事实和意图/说明。

虽然减速器可能非常愚蠢,但在我看来,它们仍然可以包含业务逻辑,例如:“计数永远不应变为负数”。
如果它们完全愚蠢,则应将它们移除并替换为通用的。

虽然这是一个非常学术的讨论,只要我们没有 action-type-is-a-noun-validator ;) 名词 +1

Couter 例子太简单了,不代表这个用例。 考虑我们同步一些数据库。 我们想显示该过程的进度条。

export function syncDb() {
    return (dispatch, getState) => {
        const {db:{client}} = getState().toJS();

        dispatch(createAction(STATUS_SYNC_DB)('syncing'));
        client.sync((progress)=> {
            dispatch(createAction(PROGRESS_SYNC_DB)(progress))
        }).then(()=> {
            dispatch(createAction(STATUS_SYNC_DB)('complete'));
        })
    };

代码不完整,但它显示了这个想法。 因为我们有异步,​​所以在 reducer 中甚至不可能做到这一点,所以它被迫在这里转储,但用户可能会在其他情况下做一些像 SYNC_STARTED 这样的操作,并在 reducer 中编写一些业务逻辑。
Reducers 是 dump 的,但我们仍然需要它们,我们可以重用它们与其他一些源同步,因为它们是 dump 的。

INIT_DB: (state, action) => state.merge(action.payload),
PROGRESS_SYNC_DB: (state, action) => state.set('dbSyncProgress', action.payload),
STATUS_SYNC_DB: (state, action) => state.set('dbSyncMode', action.payload)

我使用 immutablejs 但其他一些人可能更喜欢普通的 js 并从减速器中删除所有不可变的 js,并且应用程序仍然可以工作。 它可以轻松完成,因为所有业务逻辑都位于动作创建者中。 @ioss我所说的转储减速器是什么意思。 因此存在关注点分离。

还有一件事是,同时发送指令和事实会很棒。 但是事实应该以它们在动作创建者执行之前的方式发送,因为这样可以为动作创建者生成测试,我认为这是测试中最有趣的部分。

@lapanoid :我反对完全愚蠢的减速器。
您的减速器是一个很好的例子,说明它们是如此愚蠢,它们可以被替换为:
(state, action) => state.set(action.type, action.payload)

这意味着:如果 action.payload 从来没有被 reducer 处理或决定(因为它们不应该有业务逻辑),action 创建者也可能只是传递可合并的有效负载,从而成为它自己的 reducer 和“真实的”减速器可以被移除。

此外,如果他们那么愚蠢,那么为什么要为减速器进行热重载呢? 他们几乎不会改变。
dan 的演示视频显示了非常愚蠢的减速器,但他仍然更改了增量的数量,这使得它们包含“业务逻辑”,在我认为应该是的地方。

这些是不同的用例。

对于“存在于”服务器上的状态,reducer 是愚蠢的,因为几乎没有业务逻辑。 事实上,从模式生成减速器是有意义的。

对于“存在于”客户端的状态(例如复杂的帖子编辑器),业务逻辑在reducers 中描述。

@lapanoid与我的理解相比,我认为您已经将事实向用户转移了一层。

dispatch(createAction(STATUS_SYNC_DB)('syncing'));
调度(创建操作(PROGRESS_SYNC_DB)(进度))
dispatch(createAction(STATUS_SYNC_DB)('complete'));

这些是发生在你的 AC 逻辑中的事实(作为对象的动作)。 一组事实描述了 AC 中逻辑的执行。

用户点击某处(“事实”),它被解释为“指令”数组。 (fact)=>(List) - 这就是 actionCreator 现在实际做的。

当用户点击时,默认情况下还不是事实。 当他点击时,他将动作作为一个函数(ActionCreator)和一些导致事实的逻辑(作为一个对象的动作)来执行。 通常同步操作以 1:1 的比例转换为作为事实的动作,并且整个逻辑在减速器中完成。 异步对此造成了严重破坏,并迫使我们将所有异步代码及其所有依赖项移动到 ActionCreators,这可能导致人为的业务逻辑分离,尤其是在逻辑需要在动作创建者和化简器之间来回移动的情况下。

基于事实的减速器是松散模型。 Reducers 可以根据事实做任何有意义的事情。 他们可以很聪明,也可以很笨(只是将 AC 结果简化为状态)。

您可以使用动作作为对象来描述指令,但它是另一种更耦合的思维模型(但它可能是首选)。

我会很好地将动作作为功能(ActionCreator)和动作作为对象。

@gaearon :同意。 我并不是说愚蠢的减速器没有位置,只是我不认为所有的都应该是逻辑自由的。

我的行动对象(事实)是傲慢的,他们没有意图,他们只是说 - “这已经完成了”,你,亲爱的减速器,做你的事。 我不在乎。 我不会告诉你该怎么做,这是你的事。 我的操作对象可能会关心 reducer 是否善意地要求更好地描述发生的事情,但通常他不愿更改(以保留现有的 API 类型)。

但是,拥有 100 个减速器可能更难找到给定事实发生的所有事情。 所有事件驱动的编程和高度分离的架构都是这种情况。

@vladap

当他点击时,他将动作作为一个函数(ActionCreator)和一些导致事实>(作为对象的动作)的逻辑执行。

这是目前的设计,但我认为实际上是错误的。 如果用户迭代默认生成了一些不可变的,只有这样 AC 才会触发,我们才能测试 AC 的执行。 我认为这可以在核心中透明地完成,推动用户对每个 AC 采取额外的行动将是残酷的。
在现实世界中,当用户点击 - 噗 - 事实发生。 即使 redux 不这么认为。

我的操作对象可能会关心 reducer 是否希望更好地描述

怎么做?

@ioss

此外,如果他们那么愚蠢,那么为什么要为减速器进行热重载呢?

AC 也是热重载的 - 所以这不是一个论点

他仍然改变了增量的数量,这使得它们在我认为应该的地方包含“业务逻辑”。

他们收到 INCREMENT_COUNTER,他们不做任何决定,只做操作。 所以这里没有业务逻辑。 它们是垃圾,但即使在如此简单的情况下您仍然需要它们。 他们知道如何维护动作的状态。

我认为问题在于“Action”这个词(在 Action 和 ActionCreator 中,并且 AC 通常用作 DomEvent 处理程序)。
如果我阅读 Action,我的头脑会将它们与视图中的事件(或其他事件,例如来自后端的事件)联系起来,并且我总是想后退一步。 我可能只需要习惯它,让它进入我的潜意识。 :)

目前我正在考虑:DomEvent -> ViewActionCreator(带有 VL 的 ActionCreator 的“左”部分)-> ViewAction/ExternalAction ->(可选)带有 ViewActionHandler 的中间件/商店(带有 BL 和可能的副作用的 ActionCreator 的“右”部分) -> (Store)Action -> 减速器。
通过这种方式,可以将 ViewActions 连接到它们的 StoreAction,这可以让我有机会在 devtool 中“以视觉方式”重放 View/ExternalActions,但将 StoreActions 应用于状态,而不会重放副作用。
不确定,只是一个想法......

事情是业务逻辑(BL)在一般情况下不是同步的,所以无论如何 AC 是更好的地方。 将 BL 有时放在 AC 中,有时放在减速器中会令人困惑(也许这只是对我来说令人困惑,但无论如何 = ))

在事件命名风格方面,在我看来,过去时风格最适合您在构建 Backbone 应用程序时经常编写的从 ChildView 到 ParentView 的中间事件,例如CLOSE_BUTTON_CLICKEDDROPDOWN_CHANGED 。 然后某种控制器可能会从 UI 实现的细节中抽象出这些事件,并以命令式的方式将它们重新分配为更通用/可重用的应用程序域事件(或命令),例如CLOSE_MODALSET_SELECTED_ITEM分别为

顺便说一句,这种从 DOM 事件到应用程序域操作的转换(通常发生在单击或更改处理程序中)隐式地将一些业务逻辑泄漏到视图层 imo 中。 我不确定我对此的感受,但只要它自然地局限于智能/连接组件,它似乎没问题,因为它们无论如何都会更紧密地耦合到状态层。

我们知道,一旦一个 action 碰到了 reducer 的表面,它就一定是哑巴,只有一个类型和一个可选的有效载荷。 我对包含业务逻辑的动作创建者和中间件感到满意,但规定此类业务逻辑严格仅与将智能动作转换为愚蠢动作有关,仅此而已,这似乎很有帮助。 其他业务逻辑很可能发生在服务器上,或者是在减速器上。

Fwiw 我会支持重命名操作到命令,因为从概念上讲它似乎与命令模式非常吻合。 对我来说,操作给人的印象是操作的 _how_ 已经预先确定,这与其他地方(服务器或减速器)发生的核心业务逻辑不太匹配。 实际上,在 Redux 中,我们所做的只是将 DOM 事件转换为可用的应用程序域命令类型之一,为其提供任何必要的数据并忘记它……换句话说,我们发出命令。

如果有什么东西应该被称为“动作”,那就是当哑命令在特定时间点击中减速器时发生的事件的描述。 因此,我们在时间旅行中重播的是_动作_,而不是命令及其潜在的副作用。 reducer _acts_ 一个命令,因此执行一个具体的_action_,但这将是从图书馆用户那里抽象出来的内部实现术语,他们只需要担心发出命令......即某些事情_应该_发生的意图。

来自维基百科关于命令模式:

命令模式是一种行为设计模式,其中对象用于封装执行操作或稍后触发事件所需的所有信息。

无论如何,抱歉,如果之前已经讨论过重命名为 Commands 并决定反对,请随意忽略。 也很抱歉,如果我采取了这个偏离主题的方式,请随时指出我正确的方向。 只值我的 2 美分 :-)

我的操作对象可能会关心 reducer 是否希望更好地描述
怎么做?

这只是一个比喻:) 试图传达动作对象应该经过深思熟虑,因为一旦定义它们就很难更改,并且一些 reducer 已经与它们挂钩。

@jedrichards哈哈,现在我们有了事实、行动、指令、意图和命令 =) 有趣的是人们对同一事物的看法不同我看到转储行动/命令/事实实​​际上在某种程度上变得更聪明了,因为行动/意图/指令规定了什么接下来应该发生并携带一些关于它的信息。 而 BUTTON_CLICKED 作为事实并没有这样做,所以它是自卸车。 一个事实解释为你可能会说的一些指令。

试图传达 action 对象应该经过深思熟虑,因为一旦定义它们就很难更改,并且一些 reducer 已经与它们挂钩。

是的。 正因为如此,我想要一些清晰的动作,对它们的处理方法确实会影响整个应用程序。

事情是业务逻辑(BL)在一般情况下不是同步的,所以无论如何 AC 是更好的地方。 将 BL 有时放在 AC 中,有时放在减速器中会令人困惑(也许这只是对我来说令人困惑,但无论如何 = ))

这是当前为编写可热重载代码而付出的代价。

AC 也是热重载的 - 所以这不是一个论点

如果它们包含异步代码,则它们不可热重放,您无法确定性地进行。 Redux DevTools 在重放时忽略它们,重放对异步 AC 的结果进行操作 - 仅在操作对象上 => 热重放代码仅在减速器中。

@vladap这是有道理的,我不知道 DevTools 是这样的,谢谢。 所以它们只有在同步时才能重播? 然后我们可以始终在 AC 中定位 BL 尝试使它们尽可能同步

所以它们只有在同步时才能重播?

是的,默认 combineReducers 仅支持同步代码。 您可以编写自己的 combineReducers 并确定性地执行一些异步代码,但是因为所有减速器都必须同步直到执行下一个动作,所以净增益是有问题的 - 动作处理和渲染是耦合的(与游戏引擎中的 fe 不同)因此减速器的执行必须快速以避免无响应的用户界面。

您放入 AC 的代码越多,您可以重播/时间旅行和实时编辑的代码越少,您最终会得到一个简单的调试日志 - 在这种情况下,您可能只是直接改变而不是使用 console.log() 操作。 如果您更改 AC 代码并将其应用于已保存的操作,您将看不到更改的效果。 如果您更改 reducer 代码,您保存的操作将以不同的方式重放 -> 您可以向后移动,更改代码并向前移动时间以查看它是如何应用的。

@vladap您希望重播的副作用类型的示例是什么?

给定一个无状态的视图层,我只能想到网络交互,并且
我觉得这不是一件非常安全的事情……

我同意你之前写的,当向服务器发送命令时,他们
与我们发送给减速器的事实不同,但我们将它们混为一谈。
#313 的好实现!

在星期一,2015年8月3日,22:11 vladap [email protected]写道:

所以它们只有在同步时才能重播?

是的,默认 combineReducers 仅支持同步代码。 你可以写你的
自己的 combineReducers 并确定性地执行一些异步代码,但是
因为所有减速器都必须同步,直到执行下一个动作
净收益值得怀疑 - 动作处理和渲染是耦合的
(与游戏引擎中的 fe 不同)因此减速器的执行必须很快
以避免无响应的用户界面。

您放入 AC 的代码越多,您可以重播/时间旅行和编辑的代码就越少
实时,您最终会得到一个简单的调试日志 - 在这种情况下,您可以
可能只是直接变异,而不是使用 console.log() 操作。 如果
您更改 AC 代码并将其应用于已保存的操作,您将看不到效果
你的改变。 如果您更改减速器代码,您保存的操作将被重播
不同 -> 您可以回到过去,更改代码并向前移动时间
看看它是如何应用的。


直接回复此邮件或在 GitHub 上查看
https://github.com/gaearon/redux/issues/384#issuecomment -127393209。

哇。
(在手机上输入,请原谅简洁)

@wmertens我不想重播副作用,它在#307 中讨论过。

@jedrichards命令模式明确定义了要执行的命令,换句话说,要执行的确切行为。 是1:1的关系。 Flux 通常在 Action 和已执行的行为之间具有 1:M(许多)关系。 据我所知,具有 1:M 关系的模式称为观察者模式。

将操作重命名为命令无助于解决混淆的根本原因(这是使用的术语与默认情况下建议的设计模式)。 在某些命令模式实现中,使用操作代替命令。 在我们的上下文中,它们实际上是一回事。

当我被告知这是命令模式时,我希望一方定义要执行的内容,然后将其交给盲目执行的另一方。 如果定义了 turnOnRadio 命令,打开灯会很奇怪。

最初的 Flux 要么是一个重载的命令模式,其中动作对象能够触发更多可能不相关的行为,这可能会令人困惑。

或者它是一种重载的命令模式,其中单个行为的执行可以分布在更多商店中。 所以要打开收音机,一家商店必须插上它,而另一家商店会等到插上电源,然后再打开它。

或者它是一个观察者模式,事件奇怪地命名为动作对象,这很令人困惑。 比我期望的一方只是表示发生了某些事情而不知道接下来会发生什么。 如果一侧表示收音机已打开,则另一侧可以根据需要打开灯。

在所有情况下,这可能意味着已经执行了导致命令或事件的某些逻辑。 命令与事件只是定义耦合级别。

@wmertens我不想重播副作用,它在#307 中讨论过。

但是,是的,在 reducer 中使用 promise 是不纯的,这意味着我实际上会重播副作用。

@vladap你能详细说明你的最后一句话吗? 我没听懂。

@ioss :算了,错了。 我认为,仅使用 combineReducers 是无法做到的。

就像提到的 vladap 一样,目前并不一致。 这应该是固定的,请参阅:

改变状态的唯一方法是发出一个动作,一个描述发生了什么的对象。 (三原则,Reducer)
一个动作是一个简单的对象,表示改变状态的意图。 (词汇​​表中的动作)

一份提案:

动作:正如一些人所提到的,动作被视为表示_意图_做某事。 目前,动作创建者返回用户的 _intents_ 意图,但不知何故,这些 _intents_ 被视为事实。

事件:在事件溯源中,事件被视为过去发生的事实。 已经有一个事件存储的概念(_不是_一个动作存储)。

事件而不是动作
我认为动作创建者应该返回事件。 实际上动作创建者已经是_意图_了。 通过调用动作创建器函数,动作被执行。 在执行操作时,可以通过返回或通过返回回调函数来调度事件。

这只是一个简单的重命名,但我认为它会有所帮助。 你怎么认为?

您可以编写自己的 combineReducers 并确定性地执行一些异步代码,但是因为所有减速器都必须同步直到执行下一个动作,所以净增益是有问题的 - 动作处理和渲染是耦合的(与游戏引擎中的 fe 不同)因此减速器的执行必须快速以避免无响应的用户界面。

这我的说法也没有道理。 其他操作仍将通过。 我不知道为什么我认为游戏中有一种锁定步骤。 意识到这一点很好,因为分派相同动作的动作创建者的多次执行可能会导致竞争条件和不可预测的状态。

我认为这应该关闭以及https://github.com/gaearon/redux/issues/377#issuecomment -127703551 出于同样的原因@gaearon。 (不过这个讨论很有启发性,至少对我来说)

嗯,我认为简单地在文档中推荐一些东西是完全不同的
从重构 API。
我认为我们达成了共识,即行动常数在
过去时,命令可以是命令式的,但必须转换
动作创建者或中间件的过去时动作。

在星期二,2015年8月4日,21:25谢尔盖落聘[email protected]写道:

我认为这应该和#377一样关闭(评论)
https://github.com/gaearon/redux/issues/377#issuecomment -127703551 对于
同样的原因@gaearon https://github.com/gaearon。 (不过这
讨论很有启发性,至少对我来说)


直接回复此邮件或在 GitHub 上查看
https://github.com/gaearon/redux/issues/384#issuecomment -127728289。

哇。
(在手机上输入,请原谅简洁)

最终我们开始讨论同样的事情——行动的本质,这很好,因为它都是相互关联的。 我在这里没有看到任何共识。 如果行动是有意的,它不应该是过去时,如果是事实,则应该是过去时。 但是由于#377 的原因,不会有任何重命名

现在行动实际上以两种方式使用,因为它可以两者兼而有之。 就像光子既是波又是粒子一样,它取决于视角。

是的,但是当它到达商店时,意图已经崩溃了
事实:-)

在星期三,2015年8月5日,10:25谢尔盖落聘[email protected]写道:

现在实际上两种方式都使用了 Action,因为可以两者兼而有之。 就像光子是
波和粒子都取决于透视。


直接回复此邮件或在 GitHub 上查看
https://github.com/gaearon/redux/issues/384#issuecomment -127912543。

哇。
(在手机上输入,请原谅简洁)

我绝对不这么认为。

我认为 Intents 通常被理解为用户的意图,它们代表用户与 UI 的交互。 然后将意图转换为事件/事实或操作/命令,无论您决定将系统基于哪种模式。 我宁愿避免在任何其他上下文中使用意图术语。

用户意图可以是 showMeTop10Todos,它被转换为 TODOS_LOAD_BEGIN 和 TODOS_LOAD_SUCCESS/FAILURE。 用户不关心它们中的任何一个,它们是内部事件/事实或操作/命令。 用户有意图并且通常关心显示的结果,他不关心在两者之间必须做什么。

正如@adri 所提到的,EventSourcing 中的常用术语是 Event 或 DomainEvent。 事件也是观察者模式中的常用术语,更适合将 TODOS_LOAD_BEGIN 和 TODOS_LOAD_SUCCESS/FAILURE 视为发生了什么以及何时存在 1:M 关系。

FACT 术语用于 OLAP 分析,用于星型模式中的事实表以及维度表。 我会说 Fact 是更通用的术语,表示所分析的任何内容,它可以是事件、度量……我不知道它直接用于某些编程设计模式,尽管我并不了解它们。

我会说用户意图要高一级。 用户意图在 React 组件中转换为 ActionCreators。 我们可以获取用户意图,获取当前 Redux.state 和/或 React 组件中维护的当前本地状态,并决定我们是否实际执行 ActionCreator。

流程是 UserIntent(虚拟术语,由 DOM 事件处理程序表示)> ActionCreator > Action 对象。

也许文档中应该有四项原则。

State is a result of an immutable past.

正如本次讨论所证明的那样,这是有争议的。 我们不会在文档中规定任何特定的命名方案。

我们现在也冻结了术语,所以我们不打算介绍“事件”、“事实”或其他东西。

感谢大家的参与;-)。 关闭为不可操作。

我同意@lapanoid在这个线程中几乎没有共识。
我缺少的一件事是关于 EventSourcing 与 WAL 方法的意见,请参阅https://github.com/rackt/redux/issues/384#issuecomment -127163050 和https://github.com/rackt/redux/问题/384#issuecomment -127272825。

智能组件应该调度 CLOSE_BUTTON_CLICKED(事件源,观察者模式)还是 CLOSE_MODAL(命令模式)动作?
(我不是在谈论过去式 / naun / ... 公式)

我个人喜欢@jedrichards的观点,即智能组件可以将事件转换为通用/可重用的应用程序域操作。 我认为这在 ui 和业务逻辑之间创造了更好的分离。 当有多个事件导致相同的操作时,这也会限制操作的数量。

我认为很清楚:有些事情发生了(观察者
模式:用户点击赞按钮,服务器发送新的聊天消息),以及
你想要发生的事情(命令模式:从
服务器,显示桌面通知)并且他们正在同一个地方旅行
消息总线,调度调用。

然而。

在状态中存储的唯一有意义的东西是观察,
因为命令对状态没有直接影响。 想要的改变没有
当命令到达减速器时发生,结果
命令可能是一个新的观察。

最多,该命令可以导致观察到发出了请求,
我相信最好通过让
actioncreator 或中间件代理命令调度
观察。

因此,任何使减速器执行的操作都应写入
过去式。 其他任何东西充其量都是捷径,最糟糕的是来源
的混乱。

2015 年 8 月 19 日星期三下午 6:25 Peter Uithoven通知@github.com
写道:

我同意@lapanoid https://github.com/lapanoid有非常
在这个线程中几乎没有共识。
我缺少的一件事是对 EventSourcing 与 WAL 的看法
方法,见#384(评论)
https://github.com/rackt/redux/issues/384#issuecomment -127163050 和 #384
(评论)
https://github.com/rackt/redux/issues/384#issuecomment -127272825。

智能组件是否应该调度 CLOSE_BUTTON_CLICKED (EventSourcing,
观察者模式)或 CLOSE_MODAL(命令模式)动作?
(我不是在谈论过去式 / naun / ... 公式)

我个人喜欢@jedrichards https://github.com/jedrichards的观点
智能组件可以将事件转换为通用/可重用的应用程序域
行动。 我认为这在用户界面和业务之间创造了更好的分离
逻辑。 当有多个事件导致相同的操作时
还限制了动作的数量。


直接回复此邮件或在 GitHub 上查看
https://github.com/rackt/redux/issues/384#issuecomment -132680145。

哇。
(在手机上输入,请原谅简洁)

至于 CLOSE_BUTTON_CLICKED 与 CLOSE_MODAL,恕我直言,实际操作
应该发送的是 MODAL_GOT_HIDDEN 或只是 MODAL_HIDDEN,并且
actionCreator 可以称为 hideModal()。

2015 年 8 月 19 日星期三晚上 11:32 [email protected]
写道:

我认为很清楚:有些事情发生了(观察者
模式:用户点击赞按钮,服务器发送新的聊天消息),以及
你想要发生的事情(命令模式:从
服务器,显示桌面通知)并且他们正在同一个地方旅行
消息总线,调度调用。

然而。

在状态中存储的唯一有意义的东西是观察,
因为命令对状态没有直接影响。 想要的改变没有
当命令到达减速器时发生,结果
命令可能是一个新的观察。

该命令最多可以导致观察到一个请求是
制作,我相信最好通过让
actioncreator 或中间件代理命令调度
观察。

因此,任何使减速器执行的操作都应写入
过去式。 其他任何东西充其量都是捷径,最糟糕的是来源
的混乱。

2015 年 8 月 19 日星期三下午 6:25 Peter Uithoven通知@github.com
写道:

我同意@lapanoid https://github.com/lapanoid有非常
在这个线程中几乎没有共识。
我缺少的一件事是对 EventSourcing 与 WAL 的看法
方法,见#384(评论)
https://github.com/rackt/redux/issues/384#issuecomment -127163050 和 #384
(评论)
https://github.com/rackt/redux/issues/384#issuecomment -127272825。

智能组件是否应该调度 CLOSE_BUTTON_CLICKED (EventSourcing,
观察者模式)或 CLOSE_MODAL(命令模式)动作?
(我不是在谈论过去式 / naun / ... 公式)

我个人喜欢@jedrichards https://github.com/jedrichards的观点
智能组件可以将事件转换为通用/可重用的应用程序域
行动。 我认为这在用户界面和业务之间创造了更好的分离
逻辑。 当有多个事件导致相同的操作时
还限制了动作的数量。


直接回复此邮件或在 GitHub 上查看
https://github.com/rackt/redux/issues/384#issuecomment -132680145。

哇。
(在手机上输入,请原谅简洁)

哇。
(在手机上输入,请原谅简洁)

至于我,这个线程的最佳想法是调用动作名词,没有任何时态,如 ITEM_CREATION 我完全没问题。 我认为紧张本身就是混乱的根源。

我认为紧张本身就是混乱的根源。

我会更笼统地说,混淆的主要来源是相互冲突的心理模型的应用。

这确实是一个视角问题; 我可以很容易地争论过去时,因为对我来说最舒服的心理模型是事件溯源,但我也开始理解其他建议的观点。 我认为我们应该避免在这方面采取坚定的立场,因为我们必须明白,来自不同背景的人将受益于适合他们自然思维模式的不同解释。 选择一个建议而不是另一个建议会使某些人更难,即使对其他人更容易。 我认为,“正式”将其悬而未决,但针对博客文章、推文或播客的特定受众定制行为解释将更直接地为每个人服务。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

dmitry-zaets picture dmitry-zaets  ·  3评论

CellOcean picture CellOcean  ·  3评论

cloudfroster picture cloudfroster  ·  3评论

captbaritone picture captbaritone  ·  3评论

mickeyreiss-visor picture mickeyreiss-visor  ·  3评论