Skip to content

Commit 732760d

Browse files
philibeachambo-eDorianMaliszewski
authored
fix(use-query-params): re-render hooks (#81)
* fix(query-params):re-render hooks * fix: no compare * fix: using window.history and window.location Co-authored-by: Emmanuel Chambon <[email protected]> Co-authored-by: Dorian Maliszewski <[email protected]>
1 parent 570009f commit 732760d

File tree

4 files changed

+74
-196
lines changed

4 files changed

+74
-196
lines changed

packages/use-query-params/package.json

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
"react-dom",
88
"reactjs",
99
"hooks",
10-
"react-router-dom",
1110
"params",
1211
"query-params"
1312
],
@@ -31,15 +30,13 @@
3130
},
3231
"peerDependencies": {
3332
"react": "17.x",
34-
"react-dom": "17.x",
35-
"react-router-dom": "5.x"
33+
"react-dom": "17.x"
3634
},
3735
"devDependencies": {
3836
"@testing-library/jest-dom": "^5.11.9",
3937
"@testing-library/react": "^11.2.5",
4038
"@testing-library/react-hooks": "^5.1.0",
4139
"react": "^17.0.1",
42-
"react-dom": "^17.0.1",
43-
"react-router-dom": "^5.2.0"
40+
"react-dom": "^17.0.1"
4441
}
4542
}

packages/use-query-params/src/__tests__/index.js

Lines changed: 39 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1-
import { act, cleanup, renderHook } from '@testing-library/react-hooks'
2-
import React from 'react'
3-
import { MemoryRouter } from 'react-router-dom'
1+
import { act, renderHook } from '@testing-library/react-hooks'
42
import useQueryParam from '../index'
53

64
// eslint-disable-next-line react/prop-types
7-
const wrapper = ({ pathname = 'one', search }) => ({ children }) => (
8-
<MemoryRouter initialIndex={0} initialEntries={[{ pathname, search }]}>
9-
{children}
10-
</MemoryRouter>
11-
)
5+
const wrapper = ({ pathname = 'one', search }) => ({ children }) => {
6+
window.history.replaceState(
7+
window.history.state,
8+
null,
9+
`${pathname}?${search}`,
10+
)
11+
12+
return children
13+
}
1214

1315
describe('useQueryParam', () => {
14-
afterEach(cleanup)
15-
it('should set one object', async () => {
16+
it('should set one object', () => {
1617
const { result } = renderHook(() => useQueryParam(), {
17-
wrapper: MemoryRouter,
18+
wrapper: wrapper({ search: 'user=john' }),
1819
})
1920

2021
act(() => {
@@ -23,9 +24,9 @@ describe('useQueryParam', () => {
2324
expect(result.current.queryParams).toEqual({ user: 'John' })
2425
})
2526

26-
it('should correctly set with different value', async () => {
27+
it('should correctly set with different value', () => {
2728
const { result } = renderHook(() => useQueryParam(), {
28-
wrapper: MemoryRouter,
29+
wrapper: wrapper({ search: 'user=john' }),
2930
})
3031

3132
act(() => {
@@ -34,19 +35,22 @@ describe('useQueryParam', () => {
3435
expect(result.current.queryParams).toEqual({ user: 'John' })
3536

3637
act(() => {
37-
result.current.setQueryParams({ user: 'Doe' })
38+
result.current.setQueryParams({ user: 'Doe', name: 'Doe' })
3839
})
39-
expect(result.current.queryParams).toEqual({ user: 'Doe' })
40+
expect(result.current.queryParams).toEqual({ user: 'Doe', name: 'Doe' })
4041

4142
act(() => {
4243
result.current.setQueryParams({ user: 'Scaleway' })
4344
})
44-
expect(result.current.queryParams).toEqual({ user: 'Scaleway' })
45+
expect(result.current.queryParams).toEqual({
46+
user: 'Scaleway',
47+
name: 'Doe',
48+
})
4549
})
4650

47-
it('should set one complexe object', async () => {
51+
it('should set one complexe object', () => {
4852
const { result } = renderHook(() => useQueryParam(), {
49-
wrapper: MemoryRouter,
53+
wrapper: wrapper({ search: 'user=john' }),
5054
})
5155

5256
act(() => {
@@ -74,6 +78,7 @@ describe('useQueryParam', () => {
7478

7579
expect(result.current.queryParams).toEqual({ user: 'john' })
7680
})
81+
7782
it('should should handle array, boolean, number and string from existing location', () => {
7883
const { result } = renderHook(() => useQueryParam(), {
7984
wrapper: wrapper({
@@ -112,47 +117,37 @@ describe('useQueryParam', () => {
112117
})
113118
})
114119

115-
it('should modify updater and erase old params', () => {
116-
const updater = (prevState, nextState) => nextState
117-
const { result } = renderHook(() => useQueryParam({ updater }), {
118-
wrapper: wrapper({ search: 'user=john' }),
120+
it('should correctly set different objects before rerender', async () => {
121+
const { result, rerender } = renderHook(() => useQueryParam(), {
122+
wrapper: wrapper({ search: '' }),
119123
})
120124

121-
expect(result.current.queryParams).toEqual({ user: 'john' })
122125
act(() => {
123-
result.current.setQueryParams({
124-
lastName: 'Doe',
125-
})
126+
result.current.setQueryParams({ name: 'JOHN' })
127+
})
128+
129+
act(() => {
130+
result.current.setQueryParams({ lastName: 'Doe' })
126131
})
127132
expect(result.current.queryParams).toEqual({
133+
name: 'JOHN',
128134
lastName: 'Doe',
129135
})
130-
})
131136

132-
it('should modify updater and uppercase all news params', () => {
133-
const updater = (prevState, nextState) => ({
134-
...prevState,
135-
...Object.keys(nextState).reduce(
136-
(acc, key) => ({ ...acc, [key]: nextState[key].toUpperCase() }),
137-
{},
138-
),
139-
})
137+
rerender()
140138

141-
const { result } = renderHook(() => useQueryParam({ updater }), {
142-
wrapper: wrapper({ search: 'user=john' }),
139+
act(() => {
140+
result.current.setQueryParams({ name: 'john' })
143141
})
144142

145-
expect(result.current.queryParams).toEqual({ user: 'john' })
146-
147143
act(() => {
148-
result.current.setQueryParams({
149-
lastName: 'Doe',
150-
})
144+
result.current.setQueryParams({ test: 'Scaleway' })
151145
})
152146

153147
expect(result.current.queryParams).toEqual({
154-
user: 'john',
155-
lastName: 'DOE',
148+
name: 'john',
149+
lastName: 'Doe',
150+
test: 'Scaleway',
156151
})
157152
})
158153
})

packages/use-query-params/src/index.js

Lines changed: 23 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,36 @@
11
import { parse, stringify } from 'query-string'
22
import { useCallback, useEffect, useState } from 'react'
3-
import { useHistory } from 'react-router-dom'
43

5-
const useQueryParams = (options = {}) => {
6-
const { updater = {} } = options
7-
const {
8-
location: { search, pathname },
9-
replace,
10-
} = useHistory()
4+
const parseFormat = search =>
5+
parse(search, {
6+
parseNumbers: true,
7+
parseBooleans: true,
8+
arrayFormat: 'comma',
9+
})
1110

12-
const parseFormat = useCallback(
13-
() =>
14-
parse(search, {
15-
parseNumbers: true,
16-
parseBooleans: true,
17-
arrayFormat: 'comma',
18-
}),
19-
[search],
20-
)
11+
const stringyFormat = params =>
12+
stringify(params, {
13+
arrayFormat: 'comma',
14+
sort: (a, b) => a.localeCompare(b),
15+
})
2116

22-
const stringyFormat = useCallback(
23-
params =>
24-
stringify(params, {
25-
arrayFormat: 'comma',
26-
sort: (a, b) => a.localeCompare(b),
27-
}),
28-
[],
29-
)
17+
const useQueryParams = () => {
18+
const { search, pathname } = window.location
3019

31-
const defaultFnUpdater = useCallback(
32-
(currentQueryParams, nextQueryParams) => ({
33-
...currentQueryParams,
34-
...nextQueryParams,
35-
}),
36-
[],
37-
)
38-
const [state, setState] = useState(parseFormat())
20+
const [state, setState] = useState(parseFormat(search))
3921

40-
const setQueryParams = useCallback(
41-
nextParams => {
42-
const currentQueryParams = parseFormat()
43-
const params =
44-
updater instanceof Function
45-
? updater(currentQueryParams, nextParams)
46-
: defaultFnUpdater(currentQueryParams, nextParams)
47-
48-
setState(params)
49-
},
50-
[parseFormat, updater, defaultFnUpdater],
51-
)
22+
const setQueryParams = useCallback(nextParams => {
23+
setState(prevState => ({ ...prevState, ...nextParams }))
24+
}, [])
5225

5326
useEffect(() => {
5427
const stringifiedParams = stringyFormat(state)
55-
if (stringifiedParams !== search.replace('?', '')) {
56-
replace(`${pathname}?${stringifiedParams}`)
57-
}
58-
}, [pathname, replace, search, state, stringyFormat])
59-
28+
window.history.replaceState(
29+
window.history.state,
30+
null,
31+
`${pathname}?${stringifiedParams}`,
32+
)
33+
}, [pathname, state])
6034

6135
return {
6236
queryParams: state,

0 commit comments

Comments
 (0)