Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions docs/recipes/ReducingBoilerplate.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ const LOAD_ARTICLE = 'LOAD_ARTICLE';

Why is this beneficial? **It is often claimed that constants are unnecessary, and for small projects, this might be correct.** For larger projects, there are some benefits to defining action types as constants:

* It helps maintain the naming consistent because all action types are gathered in a single place.
* Sometimes you want to see all existing actions before working on a new feature. It happens that the action you needed was already added by somebody on the team, but you didn’t know.
* It helps keep the naming consistent because all action types are gathered in a single place.
* Sometimes you want to see all existing actions before working on a new feature. It may be that the action you need was already added by somebody on the team, but you didn’t know.
* The list of action types that were added, removed, and changed in a Pull Request, helps everyone on the team keep track of scope and implementation of new features.
* If you make a typo when importing an action constant, you will get `undefined`. This is much easier to notice than a typo when you wonder why nothing happens when the action is dispatched.

Expand Down Expand Up @@ -141,11 +141,11 @@ export const removeTodo = makeActionCreator('REMOVE_TODO', 'id');
See [redux-action-utils](https://github.com/insin/redux-action-utils) and [redux-actions](https://github.com/acdlite/redux-actions) for examples of such utilities.

Note that such utilities add magic to your code.
Are magic and indirection really worth extra few lines?
Are magic and indirection really worth it to avoid a few extra few lines of code?

## Async Action Creators

[Middleware](../Glossary.html#middleware) lets you inject a custom logic that interprets every action object before it is dispatched. Async actions are the most common use case for middleware.
[Middleware](../Glossary.html#middleware) lets you inject custom logic that interprets every action object before it is dispatched. Async actions are the most common use case for middleware.

Without any middleware, [`dispatch`](../api/Store.md#dispatch) only accepts a plain object, so we have to perform AJAX calls inside our components:

Expand Down Expand Up @@ -232,7 +232,7 @@ export default connect(state => ({
}))(Posts);
```

However, this quickly gets repetitive because different components request data from the same API endpoints. Moreover, we want to reuse some of this logic (e.g. early exit when there is cached data available) from many components.
However, this quickly gets repetitive because different components request data from the same API endpoints. Moreover, we want to reuse some of this logic (e.g., early exit when there is cached data available) from many components.

**Middleware lets us write more expressive, potentially async action creators.** It lets us dispatch something other than plain objects, and interprets the values. For example, middleware can “catch” dispatched Promises and turn them into a pair of request and success/failure actions.

Expand Down Expand Up @@ -470,7 +470,7 @@ It’s unfortunate that many still choose Flux framework based on whether it use

### Generating Reducers

Let’s write a function that lets us express reducers as object mapping from action types to handlers. For example, if we want our `todos` reducers to be defined like this:
Let’s write a function that lets us express reducers as an object mapping from action types to handlers. For example, if we want our `todos` reducers to be defined like this:

```js
export const todos = createReducer([], {
Expand All @@ -495,6 +495,6 @@ function createReducer(initialState, handlers) {
}
```

This wasn’t difficult, was it? Redux doesn’t provide such helper by default because there are many ways to write it. Maybe you want it to automatically convert plain JS objects to Immutable objects to hydrate the server state. Maybe you want to merge the returned state with the current state. There may be different approaches to “catch all” handler. All of this depends on the conventions you choose for your team on a specific project.
This wasn’t difficult, was it? Redux doesn’t provide such a helper function by default because there are many ways to write it. Maybe you want it to automatically convert plain JS objects to Immutable objects to hydrate the server state. Maybe you want to merge the returned state with the current state. There may be different approaches to a “catch all” handler. All of this depends on the conventions you choose for your team on a specific project.

Redux reducer API is `(state, action) => state`, but how you create those reducers is up to you.