Skip to content

Commit 69690c3

Browse files
committed
Explicitly document mapPropsToConfig
1 parent e8d5ba5 commit 69690c3

File tree

4 files changed

+86
-72
lines changed

4 files changed

+86
-72
lines changed

README.md

Lines changed: 80 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,14 @@ export const getQueries = (state) => state.queries;
3939
export const getEntities = (state) => state.entities;
4040

4141
const reducer = combineReducers({
42-
entities: entitiesReducer,
43-
queries: queriesReducer,
42+
entities: entitiesReducer,
43+
queries: queriesReducer,
4444
});
4545

4646
const logger = createLogger();
4747
const store = createStore(
48-
reducer,
49-
applyMiddleware(queryMiddleware(getQueries, getEntities), logger)
48+
reducer,
49+
applyMiddleware(queryMiddleware(getQueries, getEntities), logger)
5050
);
5151
```
5252

@@ -154,37 +154,51 @@ Specifying `rollback` functions are not required. However, it is recommended for
154154

155155
### `connectRequest`
156156

157-
Use the `connectRequest` higher-order component to declare network dependencies for a React component. `connectRequest` takes a function that transforms the component `props` to a request query config or an array of request query configs. Example usage:
157+
Use the `connectRequest` higher-order component to declare network dependencies for a React component.
158+
159+
`connectRequest` takes a function, `mapPropsToConfigs`, that transforms the component `props` to a request query config or an array of request query configs. You can think of `mapPropsToConfigs` similarly to `react-redux`'s `mapStateToProps` and `mapDispatchToProps`.
160+
161+
On mount, every query config returned from `mapPropsToConfigs` will result in a dispatched `requestAsync` Redux action. When the props update, `mapPropsToConfigs` is called again. All pending requests that were removed will be cancelled and all new configs will result in a dispatched `requestAsync` Redux action. On unmount, all pending requests will be cancelled.
162+
163+
Please note, just because a `requestAsync `Redux action was dispatched, does not mean that an actual network request will occur. Requests that were previously successful will not result in another network request, unless the corresponding query config has `force` set to `true`.
164+
165+
99% of the time you'll be using `react-redux`'s `connect` at the same time when you are using `connectRequest`. You might find using `redux`'s `compose` function makes this a bit more elegant.
166+
167+
Example usage:
158168

159169
```javascript
170+
import { compose } from 'redux';
160171
import { connectRequest } from 'redux-query';
161172
import { connect } from 'react-redux';
162173

163174
class Dashboard extends Component {
164-
...
175+
...
165176
}
166177

167-
const DashboardContainer = connectRequest((props) => ({
178+
const mapStateToProps = (state, props) => ({
179+
dashboard: getDashboard(state, props),
180+
});
181+
182+
const mapPropsToConfigs = props => [
183+
{
168184
url: `/api/dashboard/${props.dashboardId}`,
169185
update: {
170-
chartsById: (prevCharts, dashboardCharts) => ({
171-
...prevCharts,
172-
...dashboardCharts,
173-
}),
174-
dashboardsById: (prevDashboards, dashboards) => ({
175-
...prevDashboards,
176-
...dashboards,
177-
}),
186+
chartsById: (prevCharts, dashboardCharts) => ({
187+
...prevCharts,
188+
...dashboardCharts,
189+
}),
190+
dashboardsById: (prevDashboards, dashboards) => ({
191+
...prevDashboards,
192+
...dashboards,
193+
}),
178194
},
179-
}))(Dashboard);
195+
}
196+
];
180197

181-
const mapStateToProps = (state, props) => {
182-
return {
183-
dashboard: getDashboard(state, props),
184-
};
185-
};
186-
187-
export default connect(mapStateToProps)(DashboardContainer);
198+
export default compose(
199+
connect(mapStateToProps),
200+
connectRequest(mapPropsToConfigs)
201+
)(Dashboard);
188202
```
189203

190204
`connectRequest` passes an extra prop to the child component: `forceRequest`. Calling this function will cause the request(s) to be made again. This may be useful for polling or creating an interface to trigger refreshes.
@@ -197,16 +211,16 @@ Dispatch `mutateAsync` Redux actions to trigger mutations. `mutateAsync` takes a
197211
// src/queries/dashboard.js
198212

199213
export const createUpdateDashboardQuery = (dashboardId, newName) => ({
200-
url: `/api/${dashboardId}/update`,
201-
body: {
202-
name: newName,
203-
},
204-
update: {
205-
dashboardsById: (prevDashboardsById, newDashboardsById) => ({
206-
...prevDashboardsById,
207-
...newDashboardsById,
208-
}),
209-
},
214+
url: `/api/${dashboardId}/update`,
215+
body: {
216+
name: newName,
217+
},
218+
update: {
219+
dashboardsById: (prevDashboardsById, newDashboardsById) => ({
220+
...prevDashboardsById,
221+
...newDashboardsById,
222+
}),
223+
},
210224
});
211225

212226
// src/actions/dashboard.js
@@ -215,17 +229,17 @@ import { mutateAsync } from 'redux-query';
215229
import { createUpdateDashboardQuery } from '../queries/dashboard';
216230

217231
export const updateDashboard = (dashboardId, newName) => {
218-
return mutateAsync(createUpdateDashboardQuery(dashboardId, newName));
232+
return mutateAsync(createUpdateDashboardQuery(dashboardId, newName));
219233
};
220234

221235
// src/selectors/dashboard.js
222236

223237
export const getDashboard = (state, { dashboardId }) => {
224-
if (state.entities.dashboardsById) {
225-
return state.entities.dashboardsById[dashboardId];
226-
} else {
227-
return null;
228-
}
238+
if (state.entities.dashboardsById) {
239+
return state.entities.dashboardsById[dashboardId];
240+
} else {
241+
return null;
242+
}
229243
};
230244

231245
// src/components/Dashboard.jsx
@@ -236,21 +250,21 @@ import { updateDashboard } from '../actions/dashboard';
236250
import { getDashboard } from '../selectors/dashboard';
237251

238252
class Dashboard extends Component {
239-
...
253+
...
240254
}
241255

242256
const mapStateToProps = (state, props) => {
243-
return {
244-
dashboard: getDashboard(state, props),
245-
};
257+
return {
258+
dashboard: getDashboard(state, props),
259+
};
246260
};
247261

248262
const mapDispatchToProps = (dispatch, props) => {
249-
return {
250-
changeName: (newName) => {
251-
dispatch(updateDashboard(props.dashboardId, newName));
252-
},
253-
};
263+
return {
264+
changeName: (newName) => {
265+
dispatch(updateDashboard(props.dashboardId, newName));
266+
},
267+
};
254268
};
255269

256270
export default connect(mapStateToProps, mapDispatchToProps)(Dashboard);
@@ -260,15 +274,15 @@ When dispatching a `mutateAsync` action, you can Promise-chain on the returned v
260274

261275
```javascript
262276
const mapDispatchToProps = (dispatch, props) => {
263-
return {
264-
changeName: (newName) => {
265-
dispatch(updateDashboard(props.dashboardId, newName)).then((result) => {
266-
if (result.status !== 200) {
267-
dispatch(showUpdateDashboardFailedNotification(props.dashboardId));
268-
}
269-
});
270-
},
271-
};
277+
return {
278+
changeName: (newName) => {
279+
dispatch(updateDashboard(props.dashboardId, newName)).then((result) => {
280+
if (result.status !== 200) {
281+
dispatch(showUpdateDashboardFailedNotification(props.dashboardId));
282+
}
283+
});
284+
},
285+
};
272286
};
273287
```
274288

@@ -340,14 +354,14 @@ Network interfaces have the following interface:
340354

341355
```javascript
342356
type NetworkInterface = (
343-
url: string,
344-
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',
345-
config?: { body?: string | Object, headers?: Object, credentials?: 'omit' | 'include' } = {},
357+
url: string,
358+
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',
359+
config?: { body?: string | Object, headers?: Object, credentials?: 'omit' | 'include' } = {},
346360
) => NetworkHandler;
347361

348362
type NetworkHandler = {
349-
execute: (callback: (err: any, resStatus: number, resBody: ?Object, resText: string, resHeaders: Object) => void) => void,
350-
abort: () => void,
363+
execute: (callback: (err: any, resStatus: number, resBody: ?Object, resText: string, resHeaders: Object) => void) => void,
364+
abort: () => void,
351365
};
352366
```
353367

@@ -365,13 +379,13 @@ export const getQueries = (state) => state.queries;
365379
export const getEntities = (state) => state.entities;
366380

367381
const reducer = combineReducers({
368-
entities: entitiesReducer,
369-
queries: queriesReducer,
382+
entities: entitiesReducer,
383+
queries: queriesReducer,
370384
});
371385

372386
const store = createStore(
373-
reducer,
374-
applyMiddleware(queryMiddlewareAdvanced(myNetworkInterface)(getQueries, getEntities))
387+
reducer,
388+
applyMiddleware(queryMiddlewareAdvanced(myNetworkInterface)(getQueries, getEntities))
375389
);
376390
```
377391

site/src/demos/hello-world/client.js.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,11 @@ const mapStateToProps = state => ({
7777

7878
// Map props from `mapStateToProps` to a request query config. In this case,
7979
// the query config is constant (i.e. not parameterized by props).
80-
const mapPropsToConfig = () => helloRequest();
80+
const mapPropsToConfigs = () => helloRequest();
8181

8282
const HelloWorldContainer = compose(
8383
connect(mapStateToProps),
84-
connectRequest(mapPropsToConfig)
84+
connectRequest(mapPropsToConfigs)
8585
)(HelloWorld);
8686

8787
class App extends Component {

site/src/demos/mounting/client.js.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,11 @@ const mapStateToProps = state => ({
9797
});
9898

9999
// Map props from `mapStateToProps` to a request query config.
100-
const mapPropsToConfig = props => helloRequest(props.force);
100+
const mapPropsToConfigs = props => helloRequest(props.force);
101101

102102
const HelloWorldContainer = compose(
103103
connect(mapStateToProps),
104-
connectRequest(mapPropsToConfig)
104+
connectRequest(mapPropsToConfigs)
105105
)(HelloWorld);
106106

107107
class App extends Component {

site/src/demos/updating/client.js.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,11 @@ const mapDispatchToProps = dispatch => ({
117117
});
118118

119119
// Map props from `mapStateToProps` to a request query config.
120-
const mapPropsToConfig = props => echoRequest(props.input);
120+
const mapPropsToConfigs = props => echoRequest(props.input);
121121

122122
const EchoContainer = compose(
123123
connect(mapStateToProps, mapDispatchToProps),
124-
connectRequest(mapPropsToConfig)
124+
connectRequest(mapPropsToConfigs)
125125
)(Echo);
126126

127127
class App extends Component {

0 commit comments

Comments
 (0)