INFO

While the concepts in the “Basic” and “Advanced” tutorials are still valid, these pages are some of the oldest parts of our docs. We’ll be updating those tutorials soon to improve the explanations and show some patterns that are simpler and easier to use. Keep an eye out for those updates. We’ll also be reorganizing our docs to make it easier to find information. We recommend starting with the Redux Essentials tutorial, since it covers the key points you need to know about how to get started using Redux to write actual applications.

信息

In the basics guide, we built a simple todo application. It was fully synchronous. Every time an action was dispatched, the state was updated immediately.
在基本教程中,我们构建了一个简单的todo应用程序。它是完全同步的。每次一个action被派发,状态被立即更新。

In this guide, we will build a different, asynchronous application. It will use the Reddit API to show the current headlines for a selected subreddit. How does asynchronicity fit into Redux flow?
本教程中,我们将构建一个不同的,异步的应用程序。他将用Reddit API来展示所选子Reddit的当前标题。异步如何适应Redux流?
**

Actions

When you call an asynchronous API, there are two crucial moments in time: the moment you start the call, and the moment when you receive an answer (or a timeout).
当你调用异步API时,有两个关键时刻:你开始调用时,和当你接收答案(或者超时)的时候。

Each of these two moments usually require a change in the application state; to do that, you need to dispatch normal actions that will be processed by reducers synchronously. Usually, for any API request you’ll want to dispatch at least three different kinds of actions:
这两个时刻通常都需要改变应用程序状态;你需要派发普通action通过reducers同步被处理。通常,对于任意API请求,您都希望至少派发三种不同的操作:
**

  • An action informing the reducers that the request began.

The reducers may handle this action by toggling an isFetching flag in the state. This way the UI knows it’s time to show a spinner.

  • 通知reducers请求已开始的动作。

reducers可以通过在状态下切换isFetcheing标志来处理这个action,这样,UI知道是时候显示微调器了

  • An action informing the reducers that the request finished successfully.

The reducers may handle this action by merging the new data into the state they manage and resetting isFetching. The UI would hide the spinner, and display the fetched data.

  • 通知reducers请求成功地完成

reducers可以通过合并新数据到他们管理的状态和重置isFetching来处理此动作,UI将隐藏微调器,并显示获取的数据。

  • An action informing the reducers that the request failed.

The reducers may handle this action by resetting isFetching. Additionally, some reducers may want to store the error message so the UI can display it.

  • 通知reducers请求失败

reducers通过重置isFetching处理action。另外,一些reducers可能想要存储错误消息,以便UI可以显示它

You may use a dedicated status field in your actions:
你可以在actions使用专门的status 字段:

  1. { type: 'FETCH_POSTS' }
  2. { type: 'FETCH_POSTS', status: 'error', error: 'Oops' }
  3. { type: 'FETCH_POSTS', status: 'success', response: { ... } }

Or you can define separate types for them:
或者你可以为他们定义单独的类型:

  1. { type: 'FETCH_POSTS_REQUEST' }
  2. { type: 'FETCH_POSTS_FAILURE', error: 'Oops' }
  3. { type: 'FETCH_POSTS_SUCCESS', response: { ... } }

Choosing whether to use a single action type with flags, or multiple action types, is up to you. It’s a convention you need to decide with your team. Multiple types leave less room for a mistake, but this is not an issue if you generate action creators and reducers with a helper library like redux-actions.
选择是否使用带有标志的单一操作类型,或多种动作类型,你决定。这是您需要与团队决定的惯例。多种类型为错误留下更少的空间,但这不是问题,如果您使用诸如redux-actions之类的帮助程序库来生成动作创建者和简化器。

Whatever convention you choose, stick with it throughout the application. We’ll use separate types in this tutorial.
无论你选择哪种约定,在整个应用程序中坚持使用它。在本教程中,我们将使用单独的类型。

Synchronous Action Creators

Let’s start by defining the several synchronous action types and action creators we need in our example app. Here, the user can select a subreddit to display:
让我们从定义几种在应用程序中需要的同步action类型和action creators开始。这里,用户可以选择要显示的子subreddit:

actions.js (Synchronous)

  1. export const SELECT_SUBREDDIT = 'SELECT_SUBREDDIT'
  2. export function selectSubreddit(subreddit) {
  3. return {
  4. type: SELECT_SUBREDDIT,
  5. subreddit
  6. }
  7. }

They can also press a “refresh” button to update it:
他们也能按“刷新”按钮去更新它

  1. export const INVALIDATE_SUBREDDIT = 'INVALIDATE_SUBREDDIT'
  2. export function invalidateSubreddit(subreddit) {
  3. return {
  4. type: INVALIDATE_SUBREDDIT,
  5. subreddit
  6. }
  7. }

These were the actions governed by the user interaction. We will also have another kind of action, governed by the network requests. We will see how to dispatch them later, but for now, we just want to define them.