javascript Flux 最佳实践:在 Web API Utils 中存储调度操作、AJAX 调用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29986108/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Flux best practices: Stores dispatching actions, AJAX calls in Web API Utils?
提问by ton
I understand that this image has been the ultimate guide of most, if not all, Flux programmers. Having this flow in mind, I have a few questions:
我知道这张图片是大多数(如果不是全部)Flux 程序员的终极指南。考虑到这个流程,我有几个问题:
- Is it correct/highly advisable to have all of my
$.ajax
calls inside my Web API Utils?- Callbacks call the action creators, passing the data in the process
- If I want my Storeto make an AJAX call, I do have to call the Action Creatorfirst, right? Is it fundamentally incorrect to call a function in Web API Utilsdirectly from Store?
- Is there like a virtual one-sided arrow connecting from Storeto Action Creators?
- I have a lot of operations that do not go through views
- What are the Callbacksbetween Dispatcherand Store?
- What's the Web APIhere? Is this where you'd apply a RESTful API? Is there an example of this somewhere?
Is it okay to have a logic involved (to know which Actionto dispatch) in one of my Action Creators? Basically, this action receives the response from my AJAX call. This is a snippet:
var TransportActions = { receiveProxyMessage: function (message, status, xhr) { switch (message) { case ProxyResponses.AUTHORIZED: AppDispatcher.dispatch({ type: ActionTypes.LOGIN_SUCCESS, reply: m }); break; case ProxyResponses.UNAUTHORIZED: AppDispatcher.dispatch({ type: ActionTypes.LOGIN_FAIL, reply: m }); break; ... } } }
- 将所有
$.ajax
调用都放在Web API Utils 中是否正确/非常可取?- 回调调用动作创建者,在过程中传递数据
- 如果我想让我的Store进行AJAX 调用,我必须先调用Action Creator,对吗?直接从Store调用Web API Utils 中的函数从根本上是错误的吗?
- 有没有像从Store到Action Creators的虚拟单向箭头?
- 我有很多不经过视图的操作
- Dispatcher和Store之间的回调是什么?
- 这里的Web API是什么?这是您应用 RESTful API 的地方吗?某处有这样的例子吗?
在我的一个Action Creator 中包含逻辑(知道要调度哪个Action)是否可以?基本上,此操作接收来自我的 AJAX 调用的响应。这是一个片段:
var TransportActions = { receiveProxyMessage: function (message, status, xhr) { switch (message) { case ProxyResponses.AUTHORIZED: AppDispatcher.dispatch({ type: ActionTypes.LOGIN_SUCCESS, reply: m }); break; case ProxyResponses.UNAUTHORIZED: AppDispatcher.dispatch({ type: ActionTypes.LOGIN_FAIL, reply: m }); break; ... } } }
I've seen a lot of different answers online, but I am still not sure how I would incorporate all of them in my application. TYIA!
我在网上看到了很多不同的答案,但我仍然不确定如何将所有这些都合并到我的应用程序中。蒂亚!
回答by Retozi
Is it correct/highly advisable to have all of my $.ajax calls inside my Web API Utils? Callbacks call the action creators, passing the data in the process.
在 Web API Utils 中进行所有 $.ajax 调用是否正确/非常可取?回调调用动作创建者,在过程中传递数据。
Yes, you should put all your request into a single entity, i.e. the Web API Utils. They should dispatch the responses so any store can choose to act on them.
是的,您应该将所有请求放入一个实体中,即 Web API Utils。他们应该发送响应,以便任何商店都可以选择对它们采取行动。
I wrote a blogpost a while ago showing one way on how to handle requests http://www.code-experience.com/async-requests-with-react-js-and-flux-revisited/
不久前我写了一篇博文,展示了如何处理请求http://www.code-experience.com/async-requests-with-react-js-and-flux-revisited/
If I want my Store to make an AJAX call, I do have to call the Action Creator first, right? Is it fundamentally incorrect to call a function in Web API Utils directly from Store?
如果我想让我的 Store 进行 AJAX 调用,我必须先调用 Action Creator,对吗?直接从 Store 调用 Web API Utils 中的函数从根本上是错误的吗?
This is a good question, and as far as I have seen it, everybody does it a little different. Flux (from Facebook) does not provide a full answer.
这是一个很好的问题,就我所见,每个人的回答都略有不同。Flux(来自 Facebook)没有提供完整的答案。
There are generally two approaches you could take here:
您通常可以在这里采取两种方法:
You can make the argument that a Store should not "ask" for any data, but simply digest actions and notify the view. This means that you have to fire "fetch" actions within the components if a store are empty. This means that you will have to check on every data-listening view if it has to fetch data. This can lead to code duplication, if multiple views listen to the same Store.
The Stores are "smart" in the sense that if they get asked for data, they check if they actually have state to deliver. If they do not, they tell the API Utils to fetch data and return a pending state to the views.
Please note that this "tell the API to fetch data" is NOT a callback based operation, but a "fire and forget" one. The API will dispatch actions once the request returns.
您可以论证 Store 不应“询问”任何数据,而应简单地消化操作并通知视图。这意味着如果商店为空,您必须在组件内触发“获取”操作。这意味着您必须检查每个数据侦听视图是否必须获取数据。如果多个视图侦听同一个 Store,这可能会导致代码重复。
Stores 是“智能的”,如果他们被要求提供数据,他们会检查他们是否真的有状态要交付。如果没有,它们会告诉 API Utils 获取数据并将挂起状态返回给视图。
请注意,这个“告诉 API 获取数据”不是基于回调的操作,而是“即发即忘”的操作。一旦请求返回,API 将分派操作。
I prefer option 2 to option 1, and I've heard Bill Fisher from the Facebook team say that they do it like this as well. (see comments somewhere in the blogpost above)
与选项 1 相比,我更喜欢选项 2,而且我听到 Facebook 团队的 Bill Fisher 说他们也是这样做的。(请参阅上面博文中某处的评论)
so Noit is not fundamentally wrong to call the Api directly from the Store in my opinion.
所以不,在我看来,直接从 Store 调用 Api 从根本上来说并没有错。
Is there like a virtual one-sided arrow connecting from Store to Action Creators?
是否存在从 Store 连接到 Action Creators 的虚拟单向箭头?
Depending on your Flux implementation there might very well be.
根据您的 Flux 实现,很可能存在。
What are the Callbacks between Dispatcher and Store?
Dispatcher 和 Store 之间的回调是什么?
They are the only functions that can actually change the state in a store! each Store registers a callback with the Dispatcher. All the callbacks get invoked whenever a action is dispatched. Each callback decides if it has to mutate the store given the action type. Some Flux libraries try to hide this implementation detail from you.
它们是唯一可以真正改变商店状态的函数!每个 Store 向 Dispatcher 注册一个回调。每当一个动作被调度时,所有的回调都会被调用。每个回调决定是否必须根据操作类型改变存储。一些 Flux 库试图向你隐藏这个实现细节。
What's the Web API here? Is this where you'd apply a RESTful API? Is there an example of this somewhere?
这里的 Web API 是什么?这是您应用 RESTful API 的地方吗?某处有这样的例子吗?
I think in the picture the Web API rectangle represents the actual server, the API Utils are the ones that make calls to the server (i.e. $.ajax or superagent). It ist most likely a RESTful API serving JSONs.
我认为在图片中 Web API 矩形代表实际服务器,API Utils 是调用服务器的那些(即 $.ajax 或 superagent)。它很可能是一个为 JSON 提供服务的 RESTful API。
General advice:
一般建议:
Flux is a quite loose concept, and exact implementations change from team to team. I noticed that Facebook has changed some approaches here and there over time as well. The exact cycle is not strictly defined. There are some quite "fixed" things though:
Flux 是一个非常松散的概念,确切的实现因团队而异。我注意到 Facebook 也随着时间的推移在这里和那里改变了一些方法。确切的周期没有严格定义。不过有一些非常“固定”的事情:
- There is a Dispatcher that dispatches all actions to all stores and permits only one action at the time to prevent event-chain hell.
- Stores are action receivers, and all state must be changed through actions.
- actions are "fire and forget" (no callbacks!)
- Views receive state from the store and fire actions
- 有一个 Dispatcher 将所有动作分派到所有商店,并且一次只允许一个动作以防止事件链地狱。
- 商店是动作的接收者,所有的状态都必须通过动作来改变。
- 动作是“即发即忘”(没有回调!)
- 视图从商店接收状态并触发动作
Other things are done differently from implementation to implementation
其他事情从实现到实现不同
回答by RoryKoehein
- Is it correct/highly advisable to have all of my $.ajax calls inside my Web API Utils? Callbacks call the action creators, passing the data in the process.
- 在 Web API Utils 中进行所有 $.ajax 调用是否正确/非常可取?回调调用动作创建者,在过程中传递数据。
Absolutely.
绝对地。
- If I want my Store to make an AJAX call, I do have to call the Action Creator first, right? Is it fundamentally incorrect to call a function in Web API Utils directly from Store?
- 如果我想让我的 Store 进行 AJAX 调用,我必须先调用 Action Creator,对吗?直接从 Store 调用 Web API Utils 中的函数从根本上是错误的吗?
First, ask yourself why your store needs to do an API call. The only reason I can think of is that you want to cache the received data in the stores (I do this).
首先,问问自己为什么您的商店需要进行 API 调用。我能想到的唯一原因是您想将接收到的数据缓存在商店中(我这样做)。
In the most simple Flux implementations, all Actions are created from only the View and Server. For example, a user visits a "Profile" view, the view calls a profileRequest
action creator, the ApiUtils
is called, some data comes in, a ServerAction
is created, the ProfileStore
updates itself and the ProfileView
does accordingly.
在最简单的 Flux 实现中,所有的 Actions 都是从 View 和 Server 创建的。例如,用户访问“个人资料”视图,该视图调用profileRequest
动作创建者,ApiUtils
调用,输入一些数据,ServerAction
创建一个,ProfileStore
更新本身并相应地ProfileView
执行。
With caching: the ProfileView
ask the ProfileStore
for some profile, the store doesn't have it, so returns an empty object with state 'loading', and calls ApiUtils
to fetch that profile (and forgets about it). When the call finishes, a ServerAction
will be created, the ProfileStore
will update itself, etc. This works fine. You could also call and ActionCreator from the store, but I don't see the benefit.
使用缓存:ProfileView
请求ProfileStore
一些配置文件,商店没有它,因此返回一个状态为“正在加载”的空对象,并调用ApiUtils
获取该配置文件(并忘记它)。调用完成后,ServerAction
将创建 a,ProfileStore
将更新自身等。这很好用。您也可以从商店调用 ActionCreator,但我看不出有什么好处。
MartyJSdoes something similar. Some flux implementations do the same with promises.
MartyJS做了类似的事情。一些flux 实现对promise 做同样的事情。
I think the important part is: when data comes back into the system, a ServerActionCreator is called with the new data. This then flows back into the stores.
我认为重要的部分是:当数据返回系统时,会使用新数据调用 ServerActionCreator。然后流回商店。
I believe stores should only query data, all state-changing actions (updating stuff) should be user-initiated (come from views). Engineers from Facebook wrote about this here: https://news.ycombinator.com/item?id=7719957
我相信商店应该只查询数据,所有状态更改操作(更新内容)都应该由用户发起(来自视图)。Facebook 的工程师在这里写到了这个:https: //news.ycombinator.com/item?id=7719957
- Is there like a virtual one-sided arrow connecting from Store to Action Creators?
- 是否存在从 Store 连接到 Action Creators 的虚拟单向箭头?
If you want your stores to be smart: yes. If you want your app to be simple: no, go through Views.
如果您希望您的商店变得智能:是的。如果您希望您的应用程序简单:不,请查看视图。
- What are the Callbacks between Dispatcher and Store?
- Dispatcher 和 Store 之间的回调是什么?
These are the dispatch handlers you find in stores. The dispatcher fires an action, stores listen to this fire event and do something with the action/payload.
这些是您在商店中找到的调度处理程序。调度程序触发一个动作,存储监听这个触发事件并对动作/有效负载做一些事情。
- What's the Web API here? Is this where you'd apply a RESTful API? Is there an example of this somewhere?
- 这里的 Web API 是什么?这是您应用 RESTful API 的地方吗?某处有这样的例子吗?
This is where your ajax calls go. Typically this will mean some REST API, but could als be websockets or whatever. I've always loves this tutorial: http://fancypixel.github.io/blog/2015/01/29/react-plus-flux-backed-by-rails-api-part-2/
这是您的 ajax 调用的地方。通常这意味着一些 REST API,但也可能是 websockets 或其他什么。我一直很喜欢这个教程:http: //fancypixel.github.io/blog/2015/01/29/react-plus-flux-backed-by-rails-api-part-2/
Disclaimers: these are my interpretations of Flux. Flux itself doesn't really solve fetching data, that's why they've come up with Relay and GraphQLat FB
免责声明:这些是我对 Flux 的解释。Flux 本身并没有真正解决获取数据的问题,这就是为什么他们在 FB 上提出了Relay 和 GraphQL