Skip to content

Commit 9a14bef

Browse files
committed
Review resolutions
1 parent d41a5c1 commit 9a14bef

File tree

1 file changed

+45
-55
lines changed

1 file changed

+45
-55
lines changed

docs/using-react-redux/connect-dispatching-actions-with-mapDispatchToProps.md

Lines changed: 45 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
id: connect-dispatching-actions-with-mapDispatchToProps
33
title: Connect: Dispatching Actions with mapDispatchToProps
44
hide_title: true
5-
sidebar_label: Connect: Dispatching Actions with mapStateToProps
5+
sidebar_label: Connect: Dispatching Actions with mapDispatchToProps
66
---
77

88
# Connect: Dispatching Actions with `mapDispatchToProps`
@@ -18,9 +18,9 @@ React-Redux gives you two ways to let components dispatch actions:
1818
- By default, a connected component receives `props.dispatch` and can dispatch actions itself.
1919
- `connect` can accept an argument called `mapDispatchToProps`, which lets you create functions that dispatch when called, and pass those functions as props to your component.
2020

21-
The `mapDispatchToProps` functions are normally referred to as `mapDispatch` for short, and of course the actual variable name doesn’t matter in real code.
21+
The `mapDispatchToProps` functions are normally referred to as `mapDispatch` for short, but the actual variable name used can be whatever you want.
2222

23-
## With or Without `mapDispatchToProps`
23+
## Approaches for Dispatching
2424

2525
### Default: `dispatch` as a Prop
2626

@@ -53,23 +53,22 @@ function Counter({ count, dispatch }) {
5353
}
5454
```
5555

56-
### Providing A `mapDispatchToProps`
56+
### Providing A `mapDispatchToProps` Parameter
5757

5858
Providing a `mapDispatchToProps` allows you to specify which actions your component might need to dispatch. It lets you provide action dispatching functions as props. Therefore, instead of calling `props.dispatch(() => increment())`, you may call `props.increment()` directly. There are a few reasons why you might want to do that.
5959

6060
#### More Declarative
6161

6262
First, encapsulating the dispatch logic into function makes the implementation more declarative.
63-
Dispatching an action and let the Redux store handle the data flow is _how to_ implement the feature, it is not _what_ it does.
64-
Therefore, instead of saying:
63+
Dispatching an action and letting the Redux store handle the data flow is _how to_ implement the behavior, rather than _what_ it does.
64+
65+
A good example would be dispatching an action when a button is clicked. Connecting the button directly probably doesn't make sense conceptually, and neither does having the button reference `dispatch`.
6566

6667
```js
68+
// button needs to be aware of "dispatch"
6769
<button onClick={() => dispatch({ type: "SOMETHING" })} />
68-
```
69-
70-
you may prefer saying:
7170

72-
```js
71+
// button unaware of "dispatch",
7372
<button onClick={doSomething} />
7473
```
7574

@@ -78,7 +77,20 @@ Therefore, **if you define your own `mapDispatchToProps`, the connected componen
7877

7978
#### Pass Down Action Dispatching Logic to ( Unconnected ) Child Components
8079

81-
Furthermore, you also gain the freedom of passing down the action dispatching functions to child ( likely unconnected ) components. Now, both the connected component and its descendant need not be aware of `dispatch`, while performing their communications with the Redux store.
80+
In addition, you also gain the ability to pass down the action dispatching functions to child ( likely unconnected ) components.
81+
This allows more components to dispatch actions, while keeping them "unaware" of Redux.
82+
83+
```jsx
84+
// pass down toggleTodo to child component
85+
// making Todo able to dispatch the toggleTodo action
86+
const TodoList = ({ todos, toggleTodo }) => (
87+
<div>
88+
{todos.map(todo => (
89+
<Todo todo={todo} onClick={toggleTodo} />
90+
))}
91+
</div>
92+
);
93+
```
8294

8395
This is what React-Redux’s `connect` does — it encapsulates the logic of talking to the Redux store and lets you not worry about it. And this is what you should totally make full use of in your implementation.
8496

@@ -87,9 +99,9 @@ This is what React-Redux’s `connect` does — it encapsulates the logic of tal
8799
The `mapDispatchToProps` parameter can be of two forms. While the function form allows more customization, the object form is easy to use.
88100

89101
- **Function form**: Allows more customization, gains access to `dispatch` and optionally `ownProps`
90-
- **Object short hand form**: More declarative and easier to use
102+
- **Object shorthand form**: More declarative and easier to use
91103

92-
We recommend using the object form of `mapDispatchToProps` unless you specifically need to customize dispatching behavior in some way.
104+
> **Note:** We recommend using the object form of `mapDispatchToProps` unless you specifically need to customize dispatching behavior in some way.
93105
94106
## Defining `mapDispatchToProps` As A Function
95107

@@ -104,7 +116,8 @@ You may use this chance to write customized functions to be called by your conne
104116

105117
**`dispatch`**
106118

107-
The `mapDispatchToProps` function will be called with `dispatch` as the argument. You may use this param to wrap around the actions you wish to dispatch, or the action creators that return the actions.
119+
The `mapDispatchToProps` function will be called with `dispatch` as the first argument.
120+
You will normally make use of this by returning new functions that call `dispatch()` inside themselves, and either pass in a plain action object directly or pass in the result of an action creator.
108121

109122
```js
110123
const mapDispatchToProps = dispatch => {
@@ -117,7 +130,7 @@ const mapDispatchToProps = dispatch => {
117130
};
118131
```
119132

120-
You may take this chance to forward arguments to your action creators:
133+
You will also likely want to forward arguments to your action creators:
121134

122135
```js
123136
const mapDispatchToProps = dispatch => {
@@ -152,7 +165,7 @@ const mapDispatchToProps = (dispatch, ownProps) => {
152165

153166
Your `mapDispatchToProps` function should return a plain object:
154167

155-
- Each field in the object should be a function, calling which should automatically dispatch the action
168+
- Each field in the object will become a separate prop for your own component, and the value should normally be a function that dispatches an action when called.
156169
- If you use action creators ( as oppose to plain object actions ) inside `dispatch`, it is a convention to simply name the field key the same name as the action creator:
157170

158171
```js
@@ -198,6 +211,8 @@ Wrapping these functions by hand is tedious, so Redux provides a function to sim
198211
1. A **`function`** (an action creator) or an **`object`** (each field an action creator)
199212
2. `dispatch`
200213

214+
The wrapper functions generated by `bindActionCreators` will automatically forward all of their arguments, so you don't need to do that by hand.
215+
201216
```js
202217
import { bindActionCreators } from "redux";
203218

@@ -206,23 +221,19 @@ const decrement = () => ({ type: "DECREMENT" });
206221
const reset = () => ({ type: "RESET" });
207222

208223
// binding an action creator
209-
// returns () => dispatch(increment())
210-
bindActionCreators(increment, dispatch);
224+
// returns (...args) => dispatch(increment(...args))
225+
const boundIncrement = bindActionCreators(increment, dispatch);
211226

212227
// binding an object full of action creators
213-
bindActionCreators(
214-
{
215-
increment,
216-
decrement,
217-
reset
218-
},
228+
const boundActionCreators = bindActionCreators(
229+
{ increment, decrement, reset },
219230
dispatch
220231
);
221232
// returns
222233
// {
223-
// increment: () => dispatch(increment()),
224-
// decrement: () => dispatch(decrement()),
225-
// reset: () => dispatch(reset()),
234+
// increment: (...args) => dispatch(increment(...args)),
235+
// decrement: (...args) => dispatch(decrement(...args)),
236+
// reset: (...args) => dispatch(reset(...args)),
226237
// }
227238
```
228239

@@ -233,14 +244,7 @@ import { bindActionCreators } from "redux";
233244
// ...
234245

235246
function mapDispatchToProps(dispatch) {
236-
return bindActionCreators(
237-
{
238-
increment, // () => dispatch(increment())
239-
decrement, // () => dispatch(decrement())
240-
reset // () => dispatch(reset())
241-
},
242-
dispatch
243-
);
247+
return bindActionCreators({ increment, decrement, reset }, dispatch);
244248
}
245249

246250
// component receives props.increment, props.decrement, props.reset
@@ -252,7 +256,7 @@ connect(
252256

253257
### Manually Injecting `dispatch`
254258

255-
Since the `mapDispatchToProps` argument is supplied, the component will no longer receive the default `dispatch`. You may bring it back by adding it manually to the return of your `mapDispatchToProps`, although most of the time you shouldn’t need to do this:
259+
If the `mapDispatchToProps` argument is supplied, the component will no longer receive the default `dispatch`. You may bring it back by adding it manually to the return of your `mapDispatchToProps`, although most of the time you shouldn’t need to do this:
256260

257261
```js
258262
import { bindActionCreators } from "redux";
@@ -261,14 +265,7 @@ import { bindActionCreators } from "redux";
261265
function mapDispatchToProps(dispatch) {
262266
return {
263267
dispatch,
264-
...bindActionCreators(
265-
{
266-
increment,
267-
decrement,
268-
reset
269-
},
270-
dispatch
271-
)
268+
...bindActionCreators({ increment, decrement, reset }, dispatch)
272269
};
273270
}
274271
```
@@ -316,7 +313,7 @@ export default connect(mapState, actionCreators)(Counter);
316313

317314
// or
318315
export default connect(
319-
null,
316+
mapState,
320317
{ increment, decrement, reset }
321318
)(Counter);
322319
```
@@ -369,14 +366,7 @@ import { bindActionCreators } from "redux";
369366
function mapDispatchToProps(dispatch) {
370367
return {
371368
dispatch,
372-
...bindActionCreators(
373-
{
374-
increment,
375-
decrement,
376-
reset
377-
},
378-
dispatch
379-
)
369+
...bindActionCreators({ increment, decrement, reset }, dispatch)
380370
};
381371
}
382372
```
@@ -387,7 +377,7 @@ There are discussions regarding whether to provide `dispatch` to your components
387377

388378
### Can I `mapDispatchToProps` without `mapStateToProps` in Redux?
389379

390-
Yes. You can skip the first parameter by passing `undefined` or `null`. Your component will not subscribe to the store, and gain dispatch props defined by `mapStateToProps`.
380+
Yes. You can skip the first parameter by passing `undefined` or `null`. Your component will not subscribe to the store, and will still receive the dispatch props defined by `mapStateToProps`.
391381

392382
```js
393383
connect(
@@ -398,7 +388,7 @@ connect(
398388

399389
### Can I call `store.dispatch`?
400390

401-
It is an anti-pattern to use `store.dispatch` which you may retrieve from the `store` in context. As explained in [Redux's FAQ on store setup](https://redux.js.org/faq/storesetup#can-or-should-i-create-multiple-stores-can-i-import-my-store-directly-and-use-it-in-components-myself), any direct access of the store in a component is not recommended, whether it be via direct import or from context. Let React-Redux’s `connect` handle the access to the store, and use the `dispatch` it passes to the props to dispatch actions.
391+
It's an anti-pattern to interact with the store directly in a React component, whether it's an explicit import of the store or accessing it via context (see the [Redux FAQ entry on store setup](https://redux.js.org/faq/storesetup#can-or-should-i-create-multiple-stores-can-i-import-my-store-directly-and-use-it-in-components-myself) for more details). Let React-Redux’s `connect` handle the access to the store, and use the `dispatch` it passes to the props to dispatch actions.
402392

403393
## Links and References
404394

0 commit comments

Comments
 (0)