You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/advanced/AsyncActions.md
+12-12Lines changed: 12 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -115,7 +115,7 @@ function receivePosts(subreddit, json) {
115
115
This is all we need to know for now. The particular mechanism to dispatch these actions together with network requests will be discussed later.
116
116
117
117
> ##### Note on Error Handling
118
-
118
+
>
119
119
> In a real app, you'd also want to dispatch an action on request failure. We won't implement error handling in this tutorial, but the [real world example](../introduction/Examples.md#real-world) shows one of the possible approaches.
120
120
121
121
## Designing the State Shape
@@ -163,11 +163,11 @@ There are a few important bits here:
163
163
- For every list of items, you'll want to store `isFetching` to show a spinner, `didInvalidate` so you can later toggle it when the data is stale, `lastUpdated` so you know when it was fetched the last time, and the `items` themselves. In a real app, you'll also want to store pagination state like `fetchedPageCount` and `nextPageUrl`.
164
164
165
165
> ##### Note on Nested Entities
166
-
166
+
>
167
167
> In this example, we store the received items together with the pagination information. However, this approach won't work well if you have nested entities referencing each other, or if you let the user edit items. Imagine the user wants to edit a fetched post, but this post is duplicated in several places in the state tree. This would be really painful to implement.
168
-
168
+
>
169
169
> If you have nested entities, or if you let users edit received entities, you should keep them separately in the state as if it was a database. In pagination information, you would only refer to them by their IDs. This lets you always keep them up to date. The [real world example](../introduction/Examples.md#real-world) shows this approach, together with [normalizr](https://github.com/paularmstrong/normalizr) to normalize the nested API responses. With this approach, your state might look like this:
170
-
170
+
>
171
171
> ```js
172
172
> {
173
173
> selectedSubreddit:'frontend',
@@ -206,15 +206,15 @@ There are a few important bits here:
206
206
> }
207
207
> }
208
208
>```
209
-
209
+
>
210
210
> In this guide, we won't normalize entities, but it's something you should consider for a more dynamic application.
211
211
212
212
## Handling Actions
213
213
214
214
Before going into the details of dispatching actions together with network requests, we will write the reducers for the actions we defined above.
215
215
216
216
> ##### Note on Reducer Composition
217
-
217
+
>
218
218
> Here, we assume that you understand reducer composition with [`combineReducers()`](../api/combineReducers.md), as described in the [Splitting Reducers](../basics/Reducers.md#splitting-reducers) section on the [basics guide](../basics/README.md). If you don't, please [read it first](../basics/Reducers.md#splitting-reducers).
219
219
220
220
#### `reducers.js`
@@ -390,18 +390,18 @@ export function fetchPosts(subreddit) {
390
390
```
391
391
392
392
> ##### Note on `fetch`
393
-
393
+
>
394
394
> We use [`fetch` API](https://developer.mozilla.org/en/docs/Web/API/Fetch_API) in the examples. It is a new API for making network requests that replaces `XMLHttpRequest` for most common needs. Because most browsers don't yet support it natively, we suggest that you use [`cross-fetch`](https://github.com/lquixada/cross-fetch) library:
395
-
395
+
>
396
396
> ```js
397
397
>// Do this in every file where you use `fetch`
398
398
>importfetchfrom'cross-fetch'
399
399
>```
400
-
400
+
>
401
401
> Internally, it uses [`whatwg-fetch` polyfill](https://github.com/github/fetch) on the client, and [`node-fetch`](https://github.com/bitinn/node-fetch) on the server, so you won't need to change API calls if you change your app to be [universal](https://medium.com/@mjackson/universal-javascript-4761051b7ae9).
402
-
402
+
>
403
403
> Be aware that any `fetch` polyfill assumes a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) polyfill is already present. The easiest way to ensure you have a Promise polyfill is to enable Babel's ES6 polyfill in your entry point before any other code runs:
404
-
404
+
>
405
405
> ```js
406
406
>// Do this once before any other code in your app
407
407
>import'babel-polyfill'
@@ -515,7 +515,7 @@ store
515
515
```
516
516
517
517
> ##### Note about Server Rendering
518
-
518
+
>
519
519
> Async action creators are especially convenient for server rendering. You can create a store, dispatch a single async action creator that dispatches other async action creators to fetch data for a whole section of your app, and only render after the Promise it returns, completes. Then your store will already be hydrated with the state you need before rendering.
520
520
521
521
[Thunk middleware](https://github.com/gaearon/redux-thunk) isn't the only way to orchestrate asynchronous actions in Redux:
Copy file name to clipboardExpand all lines: docs/advanced/Middleware.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -32,7 +32,7 @@ How do we approach this with Redux?
32
32
The most naïve solution is just to log the action and the next state yourself every time you call [`store.dispatch(action)`](../api/Store.md#dispatch). It's not really a solution, but just a first step towards understanding the problem.
33
33
34
34
> ##### Note
35
-
35
+
>
36
36
> If you're using [react-redux](https://github.com/reduxjs/react-redux) or similar bindings, you likely won't have direct access to the store instance in your components. For the next few paragraphs, just assume you pass the store down explicitly.
Copy file name to clipboardExpand all lines: docs/advanced/UsageWithReactRouter.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,7 +20,7 @@ So you want to do routing with your Redux app. You can use it with [React Router
20
20
Before integrating React Router, we need to configure our development server. Indeed, our development server may be unaware of the declared routes in React Router configuration. For example, if you access `/todos` and refresh, your development server needs to be instructed to serve `index.html` because it is a single-page app. Here's how to enable this with popular development servers.
21
21
22
22
> ### Note on Create React App
23
-
23
+
>
24
24
> If you are using Create React App, you won't need to configure a fallback URL, it is automatically done.
Now that you know how to do basic routing, you can learn more about [React Router API](https://reacttraining.com/react-router/)
222
222
223
223
> ##### Note About Other Routing Libraries
224
-
224
+
>
225
225
> _Redux Router_ is an experimental library, it lets you keep entirely the state of your URL inside your redux store. It has the same API with React Router API but has a smaller community support than react-router.
226
-
226
+
>
227
227
> _React Router Redux_ creates a binding between your redux app and react-router and it keeps them in sync. Without this binding, you will not be able to rewind the actions with Time Travel. Unless you need this, React Router and Redux can operate completely apart.
Copy file name to clipboardExpand all lines: docs/api/Store.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,7 +14,7 @@ A store is not a class. It's just an object with a few methods on it.
14
14
To create it, pass your root [reducing function](../Glossary.md#reducer) to [`createStore`](createStore.md).
15
15
16
16
> ##### A Note for Flux Users
17
-
17
+
>
18
18
> If you're coming from Flux, there is a single important difference you need to understand. Redux doesn't have a Dispatcher or support many stores. **Instead, there is just a single store with a single root [reducing function](../Glossary.md#reducer).** As your app grows, instead of adding stores, you split the root reducer into smaller reducers independently operating on the different parts of the state tree. You can use a helper like [`combineReducers`](combineReducers.md) to combine them. This is similar to how there is just one root component in a React app, but it is composed out of many small components.
19
19
20
20
### Store Methods
@@ -46,7 +46,7 @@ The store's reducing function will be called with the current [`getState()`](#ge
46
46
> ##### A Note for Flux Users
47
47
>
48
48
> If you attempt to call `dispatch` from inside the [reducer](../Glossary.md#reducer), it will throw with an error saying “Reducers may not dispatch actions.” This is similar to “Cannot dispatch in a middle of dispatch” error in Flux, but doesn't cause the problems associated with it. In Flux, a dispatch is forbidden while Stores are handling the action and emitting updates. This is unfortunate because it makes it impossible to dispatch actions from component lifecycle hooks or other benign places.
49
-
49
+
>
50
50
> In Redux, subscriptions are called after the root reducer has returned the new state, so you _may_ dispatch in the subscription listeners. You are only disallowed to dispatch inside the reducers because they must have no side effects. If you want to cause a side effect in response to an action, the right place to do this is in the potentially async [action creator](../Glossary.md#action-creator).
Copy file name to clipboardExpand all lines: docs/api/combineReducers.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -34,7 +34,7 @@ You can control state key names by using different keys for the reducers in the
34
34
A popular convention is to name reducers after the state slices they manage, so you can use ES6 property shorthand notation: `combineReducers({ counter, todos })`. This is equivalent to writing `combineReducers({ counter: counter, todos: todos })`.
35
35
36
36
> ##### A Note for Flux Users
37
-
37
+
>
38
38
> This function helps you organize your reducers to manage their own slices of state, similar to how you would have different Flux Stores to manage different state. With Redux, there is just one store, but `combineReducers` helps you keep the same logical division between reducers.
> You don't have to define action type constants in a separate file, or even to define them at all. For a small project, it might be easier to just use string literals for action types. However, there are some benefits to explicitly declaring constants in larger codebases. Read [Reducing Boilerplate](../recipes/ReducingBoilerplate.md) for more practical tips on keeping your codebase clean.
36
36
37
37
Other than `type`, the structure of an action object is really up to you. If you're interested, check out [Flux Standard Action](https://github.com/acdlite/flux-standard-action) for recommendations on how actions could be constructed.
Copy file name to clipboardExpand all lines: docs/basics/Reducers.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -37,7 +37,7 @@ You'll often find that you need to store some data, as well as some UI state, in
37
37
```
38
38
39
39
> ##### Note on Relationships
40
-
40
+
>
41
41
> In a more complex app, you're going to want different entities to reference each other. We suggest that you keep your state as normalized as possible, without any nesting. Keep every entity in an object stored with an ID as a key, and use IDs to reference it from other entities, or lists. Think of the app's state as a database. This approach is described in [normalizr's](https://github.com/paularmstrong/normalizr) documentation in detail. For example, keeping `todosById: { id -> todo }` and `todos: array<id>` inside the state would be a better idea in a real app, but we're keeping the example simple.
42
42
43
43
## Handling Actions
@@ -111,13 +111,13 @@ Note that:
111
111
2.**We return the previous `state` in the `default` case.** It's important to return the previous `state` for any unknown action.
112
112
113
113
> ##### Note on `Object.assign`
114
-
114
+
>
115
115
> [`Object.assign()`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) is a part of ES6, and is not supported by older browsers. To support them, you will need to either use a polyfill, a [Babel plugin](https://www.npmjs.com/package/babel-plugin-transform-object-assign), or a helper from another library like [`_.assign()`](https://lodash.com/docs#assign).
116
116
117
117
> ##### Note on `switch` and Boilerplate
118
-
118
+
>
119
119
> The `switch` statement is _not_ the real boilerplate. The real boilerplate of Flux is conceptual: the need to emit an update, the need to register the Store with a Dispatcher, the need for the Store to be an object (and the complications that arise when you want a universal app). Redux solves these problems by using pure reducers instead of event emitters.
120
-
120
+
>
121
121
> It's unfortunate that many still choose a framework based on whether it uses `switch` statements in the documentation. If you don't like `switch`, you can use a custom `createReducer` function that accepts a handler map, as shown in [“reducing boilerplate”](../recipes/ReducingBoilerplate.md#reducers).
122
122
123
123
## Handling More Actions
@@ -379,9 +379,9 @@ function reducer(state = {}, action) {
379
379
All [`combineReducers()`](../api/combineReducers.md) does is generate a function that calls your reducers **with the slices of state selected according to their keys**, and combines their results into a single object again. [It's not magic.](https://github.com/reduxjs/redux/issues/428#issuecomment-129223274) And like other reducers, `combineReducers()` does not create a new object if all of the reducers provided to it do not change state.
380
380
381
381
> ##### Note for ES6 Savvy Users
382
-
382
+
>
383
383
> Because `combineReducers` expects an object, we can put all top-level reducers into a separate file, `export` each reducer function, and use `import * as reducers` to get them as an object with their names as the keys:
Copy file name to clipboardExpand all lines: docs/faq/General.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -94,5 +94,5 @@ Redux can be used as a data store for any UI layer. The most common usage is wit
94
94
Redux is originally written in ES6 and transpiled for production into ES5 with Webpack and Babel. You should be able to use it regardless of your JavaScript build process. Redux also offers a UMD build that can be used directly without any build process at all. The [counter-vanilla](https://github.com/reduxjs/redux/tree/master/examples/counter-vanilla) example demonstrates basic ES5 usage with Redux included as a `<script>` tag. As the relevant pull request says:
95
95
96
96
> The new Counter Vanilla example is aimed to dispel the myth that Redux requires Webpack, React, hot reloading, sagas, action creators, constants, Babel, npm, CSS modules, decorators, fluent Latin, an Egghead subscription, a PhD, or an Exceeds Expectations O.W.L. level.
97
-
97
+
>
98
98
> Nope, it's just HTML, some artisanal `<script>` tags, and plain old DOM manipulation. Enjoy!
0 commit comments