使用 Flux 和 React 处理 UI 状态

Posted

技术标签:

【中文标题】使用 Flux 和 React 处理 UI 状态【英文标题】:Handling UI state with Flux and React 【发布时间】:2015-08-06 04:40:54 【问题描述】:

使用 MVC(尤其是 Angular),当我想更改 ui 状态以响应数据更改时,我可以使用 Callback 或 Promise 在控制器级别进行处理,如下所示:

API.voteUp(ITEM_ID).then(function () 
  $scope.isOpen = false;
);

使用 Flux 时,我们会触发一个动作,例如:

ItemActions.voteUp(ITEM_ID)

但是没有办法直接对动作做出反应

我确实理解它背后的原因,知道大多数状态应该存在于存储中,并且存储应该监听 VOTE_UP 操作并相应地更改 UI 状态。但是感觉如果我需要为每个小 UI 都打开一个 Store,它的扩展性就不会很好。 我觉得 Flux 和 View 会很快耦合起来。

以下是演示问题的两个场景。 目标是关闭 Item 组件以响应操作 并且不要弄乱其他组件的状态

这里提供的演示代码: https://github.com/asfktz/flux-ui-state-test

(我正在使用 Alt Flux,但实现并不重要)

场景 A:处理 UI 状态以响应 Action

1。打开项目 A 和项目 B

2。为 A 项投票

3。 'VOTE_UP' 动作被触发。

项目 A 应关闭以响应操作 - 而不是在此之前

(例如,如果操作失败,它应该保持打开状态)

场景 B:处理相同操作的两个不同、不相关的组件不应相互干扰。

1。在两个列表中打开项目 A

2。投票给列表 B 中的项目 A。

3。列表 B 的项目 A 触发 'VOTE_UP' 操作

两个名单上的投票更新。

只有列表 B 的项目 A 应该关闭

注意事项:

This blog post描述同样的问题

【问题讨论】:

我实际上没有看到这个问题。为什么不在调度期间在有效负载中使用标识符?或者对每个投票使用单独的操作。 “但感觉如果我需要为每个小 UI 都打开一个商店,它的扩展性不会很好” - 想想一个商店处理 所有 数据的商店视图包含的。然后将数据视为不可变的!因此,它的扩展性非常好。可能是我误解了这里的问题..? 澄清:在场景 BI 中,将您的数据模型视为 [ name: 'Votes list A', items: [ name: 'Item A', votes: count: 101 , ,...] , name: 'Votes list B', items: [ name: 'Item A', votes: count: 42 , ] 而不是每个数据存储只有一个列表 @Hulvej,我相信使用保存当前视图所有状态的商店是一个很好的解决方案,但它有缺点。即使页面上不存在视图,商店也会更新。这意味着如果列表 A 和列表 B 在不同的路线上,当一个触发 'VOTE_UP' 时,第二个列表也会关闭该项目。 但这就是重点。商店不知道那里的订户 - 他们不应该知道。我猜您的“关闭”状态也将保存在数据存储中。不同的视图和它们的可见性是不相关的。 您的编程问题是什么?这似乎更像是目前所写的一种观点和声明。 【参考方案1】:

目标是关闭 Item 组件以响应操作,并且不要弄乱其他组件的状态

将商店视为状态袋。如果 List A 和 List B 应该有完全独立的数据,我会这样做:

render () 
    return (
        <div className="main">
            <div className="votes-block">
                <h2>Votes List A</h2>
                <List items=this.state.itemsA/>
            </div>
            <div className="votes-block">
                <h2>Votes List B</h2>
                <List items=this.state.itemsB/>
            </div>
        </div>
    )

基本上必须为您的两个项目维护两个项目itemsA and itemsB

【讨论】:

它与提议的项目相同。就像应用程序中允许投票的两个不同区域一样。问题是如果他们都触发了“VOTE_UP”,我们如何区分要关闭哪个列表? 顺便提一下:在那个 repo 上你忘了提交 alt export alt.jsx。要回答这个问题,如果它们是相同的项目,那么它们代表相同的数据对吗?如果是这样,一个更新一个更新没有意义。如果它是 ProfileStore,则相同,其中包含您的名字和姓氏。如果有两个地方显示此内容,您希望更新这些内容。 总而言之,基本上,当涉及到数据时,您需要一个事实来源,至少 Flux 是这样描述它的。如果两个组件都依赖于该事实来源,那么它们都应该更新。

以上是关于使用 Flux 和 React 处理 UI 状态的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Flux 处理有状态的 DOM 元素

如何处理 React/Flux 中的保存状态?

react容器组件和UI组件

React/Flux 存储不会改变它的状态

React Js - Flux 中的状态管理

将 Flux 存储中的 Immutable.js 映射与内部 React 组件状态合并