在使用Flux时,保持UI与ajax调用同步的惯用方法是什么?

时间:2015-06-29 20:47:06

标签: javascript ajax reactjs reactjs-flux flux

一般问题:我们说我有一个按钮,其中一个onClick处理程序调用一个动作创建者。该动作执行ajax调用,当ajax响应时调度消息,这在某种程度上影响UI。鉴于这种基本模式,没有什么能阻止用户多次单击此按钮,从而多次运行ajax调用。

这在React或Flux文档中似乎没有涉及到(据我所见),所以我试图自己想出一些方法。< / p>

以下是那些方法

  • 对执行ajax调用的方法使用lodash.throttle,以便快速连续多次点击不会创建多个调用。
  • 对方法使用lodash.debounce,以便只有在用户没有完成任何活动时才会调用ajax。这就是我在更改时对文本字段进行半实时更新的方式。
  • 发送&#34;正在更新&#34;首次调用操作时向商店发送消息,然后发送&#34;完成&#34; ajax调用返回时的消息。做一些事情,比如在初始消息上禁用输入,然后在第二个消息上重新启用。

第三种方法在功能方面似乎是最好的,因为它允许您使用户界面准确反映正在发生的事情,但它也令人难以置信的冗长。它充满了大量的额外状态,处理程序方法等等所有事情......

我觉得这些方法中的任何一种都不是惯用的。是什么?

2 个答案:

答案 0 :(得分:1)

我认为第三种方法是正确的方法,但我不认为它是冗长的。我看到的很多React代码都错过了React的精神,以及它非常小的可组合组件的想法。当创建大型单片组件时,是的,事情会变得非常混乱。

但是如果有问题的按钮是它自己的组件,那么它可以根据其状态来处理渲染。当用户单击该按钮时,该组件的状态会发生变化 - 并且它会以不能再次单击的方式呈现它。

一旦商店通知该组件已更改,组件可以将其状态设置回来 - 并随之重新呈现自己。

这是一个非常直接的过程;它只需要将页面视为一个小型可组合单元的集合。

答案 1 :(得分:1)

哈尔非常正确。调度多条消息是最常用的方法。

但是,我会谨慎地发送IS_UPDATING消息。这使得对代码的推理更加困难,因为对于每个AJAX操作,您一次都会调度多个操作。

惯用解决方案是将您的AJAX“操作”(action-creator-actions)拆分为三个已分派的操作:MY_ACTIONMY_ACTION_SUCCESSMY_ACTION_FAILURE,正确处理每个实例,以及在此过程中跟踪“待定”。

例如:

// MyActionCreator.js

// because this is in a closure, you can even use the promise 
// or whatever you want as a sort of "ID" to handle multiple
// requests at one time.
postMessage() {
    dispatch('POST_MESSAGE', { ... } );
    api.slowMessagePostingAjaxThingy().then(
        (success) => { dispatch('POST_MESSAGE_SUCCESS', { ... }); },
        (failure) => { dispatch('POST_MESSAGE_FAILURE', { ... }); }
    );
}

// MyStore.js

on('POST_MESSAGE', (payload) => { /* do stuff */ });
on('POST_MESSAGE_SUCCESS', (payload) => { /* handle success */ });
on('POST_MESSAGE_FAILURE', (payload) => { /* handle failure */ });

与您的替代解决方案相比,这可以带来几个好处:

  1. 您的商店专门控制商品是否有待处理。您不必担心在UI代码中更改操作的UI状态:您可以让您的UI专门查看商店的pending属性以获取真相。这可能是使用Flux而不是MVC系统的最大原因。
  2. 您有一个干净的界面来执行您的操作。很容易推理并轻松地将其他商店附加到此数据(如果您有LatestMessageStore或其他内容,则可以轻松订阅这些事件)。正如哈尔建议的那样,这比使用IS_UPDATING更有好处。
  3. 你保存你的lodash电话,因为它们在语义上有意义 - 就像你可能被合法数据(文本字段)淹没一样。
  4. 您可以轻松切换乐观更新(调用POST_MESSAGE时更改商店)或悲观更新(更改POST_MESSAGE_SUCCESS上的商店)。