Skip to content

Commit f6c8d9f

Browse files
committed
feat: Added queryParams that will extract query parameters and add them to props
refactor: Remove the first parameter and accept it in the object instead
1 parent 8c2d40e commit f6c8d9f

File tree

3 files changed

+81
-9
lines changed

3 files changed

+81
-9
lines changed

src/__snapshots__/index.test.tsx.snap

+12
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,24 @@ exports[`withParams should extract a single param 1`] = `
66
</span>
77
`;
88

9+
exports[`withParams should extract a single query parameter 1`] = `
10+
<span>
11+
/login
12+
</span>
13+
`;
14+
915
exports[`withParams should extract multiple params 1`] = `
1016
<span>
1117
1 - ben
1218
</span>
1319
`;
1420

21+
exports[`withParams should extract multiple query parameters 1`] = `
22+
<span>
23+
/login - 1489995623368
24+
</span>
25+
`;
26+
1527
exports[`withParams should extract params with exactly false 1`] = `
1628
<span>
1729
1 - ben

src/index.test.tsx

+38-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {withParams} from './index'
66

77
describe('withParams', () => {
88
it('should extract a single param', () => {
9-
const ShowName = withParams('name', {match: '/user/:name'})(({name}) =>
9+
const ShowName = withParams({params: 'name', match: '/user/:name'})(({name}) =>
1010
<span>{name}</span>
1111
)
1212

@@ -20,7 +20,7 @@ describe('withParams', () => {
2020
})
2121

2222
it('should extract multiple params', () => {
23-
const ShowIdAndName = withParams(['id', 'name'], {match: '/user/:id/:name'})(({id, name}) =>
23+
const ShowIdAndName = withParams({params: ['id', 'name'], match: '/user/:id/:name'})(({id, name}) =>
2424
<span>{id} - {name}</span>
2525
)
2626

@@ -34,7 +34,8 @@ describe('withParams', () => {
3434
})
3535

3636
it('should extract params with exactly false', () => {
37-
const ShowIdAndName = withParams(['id', 'name'], {
37+
const ShowIdAndName = withParams({
38+
params: ['id', 'name'],
3839
match: '/user/:id/:name',
3940
exactly: false,
4041
})(({id, name}) =>
@@ -49,4 +50,38 @@ describe('withParams', () => {
4950

5051
expect(toJson(wrapper)).toMatchSnapshot()
5152
})
53+
54+
it('should extract a single query parameter', () => {
55+
const Display = withParams({
56+
queryParams: 'next',
57+
match: '/users',
58+
})(({next}) =>
59+
<span>{next}</span>
60+
)
61+
62+
const wrapper = render(
63+
<Router initialEntries={['/users?next=/login']}>
64+
<Display />
65+
</Router>
66+
)
67+
68+
expect(toJson(wrapper)).toMatchSnapshot()
69+
})
70+
71+
it('should extract multiple query parameters', () => {
72+
const Display = withParams({
73+
queryParams: ['next', 'timestamp'],
74+
match: '/users',
75+
})(({next, timestamp}) =>
76+
<span>{next} - {timestamp}</span>
77+
)
78+
79+
const wrapper = render(
80+
<Router initialEntries={['/users?next=/login&timestamp=1489995623368']}>
81+
<Display />
82+
</Router>
83+
)
84+
85+
expect(toJson(wrapper)).toMatchSnapshot()
86+
})
5287
})

src/index.tsx

+31-6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import {parse} from 'querystring'
12
import * as React from 'react'
23
import {ReactType} from 'react'
34
import DefaultRoute from 'react-router/Route'
@@ -15,42 +16,66 @@ function extractParams(names, params) {
1516
return newProps
1617
}
1718

19+
function extractQueryParams(queryParamNames, queryString) {
20+
return extractParams(queryParamNames, parse(queryString.substr(1)))
21+
}
22+
1823
export type Options = {
24+
params?: string|Array<string>,
1925
match?: string
2026
exactly?: boolean
2127
state?: string|Array<string>
2228
routeComponent?: ReactType
2329
routeProps?: any
30+
queryParams?: string|Array<string>
2431
}
2532

2633
/**
2734
* HOC for extracting router params.
2835
*
2936
* Example:
3037
*
31-
* ```
32-
* const ShowName = withParams('name', {match: '/user/:name'})(({name}) =>
38+
* ```typescript
39+
* const ShowName = withParams({params: 'name', match: '/user/:name'})(({name}) =>
3340
* <span>{name}</span>
3441
* )
3542
* ```
43+
*
44+
* ```typescript
45+
* const ShowIdAndName = withParams({params: ['id', 'name'], match: '/user/:id/:name'})(({id, name}) =>
46+
* <span>{id}{name}</span>
47+
* )
48+
* ```
3649
*/
37-
export const withParams = (names, {match, exactly = true, state, routeComponent: Route = DefaultRoute, routeProps}: Options = {}) => WrappedComponent => {
50+
export const withParams = (
51+
{
52+
params: paramsNames, match, exactly = true,
53+
state, routeComponent: Route = DefaultRoute,
54+
routeProps, queryParams,
55+
}: Options = {}
56+
) => WrappedComponent => {
3857
const displayName = wrapDisplayName(WrappedComponent, 'withParams')
3958

40-
names = Array.isArray(names) ? names : [names]
59+
paramsNames = Array.isArray(paramsNames) ? paramsNames : [paramsNames]
60+
queryParams = Array.isArray(queryParams) ? queryParams : [queryParams]
61+
4162
if (state) {
4263
state = Array.isArray(state) ? state : [state]
4364
}
4465

4566
if (match) {
4667
return setDisplayName(displayName)(props =>
4768
<Route {...routeProps} exact={exactly} path={match} render={({match: {params} = {params: []}, location}) =>
48-
<WrappedComponent {...props} {...extractParams(names, params)} {...extractParams(state, location.state)} />
69+
<WrappedComponent {...props}
70+
{...extractParams(paramsNames, params)}
71+
{...extractParams(state, location.state)}
72+
{...extractQueryParams(queryParams, location.search)}
73+
/>
4974
} />
5075
)
5176
}
5277

5378
return setDisplayName(displayName)(
54-
props => <WrappedComponent {...props} {...extractParams(names, props.params)} />
79+
props => <WrappedComponent {...props} {...extractParams(paramsNames, props.params)} />
5580
)
5681
}

0 commit comments

Comments
 (0)