1
- import { useCallback , useMemo , useEffect , useState } from 'react' ;
1
+ import { useCallback , useMemo , useEffect , useState , useRef } from 'react' ;
2
2
import { useSelector , useDispatch , shallowEqual } from 'react-redux' ;
3
3
import { parse , stringify } from 'query-string' ;
4
4
import lodashDebounce from 'lodash/debounce' ;
5
- import set from 'lodash/set' ;
6
5
import pickBy from 'lodash/pickBy' ;
7
6
import { useHistory , useLocation } from 'react-router-dom' ;
8
7
9
8
import queryReducer , {
10
9
SET_FILTER ,
10
+ HIDE_FILTER ,
11
+ SHOW_FILTER ,
11
12
SET_PAGE ,
12
13
SET_PER_PAGE ,
13
14
SET_SORT ,
@@ -16,7 +17,6 @@ import queryReducer, {
16
17
import { changeListParams , ListParams } from '../actions/listActions' ;
17
18
import { SortPayload , ReduxState , FilterPayload } from '../types' ;
18
19
import removeEmpty from '../util/removeEmpty' ;
19
- import removeKey from '../util/removeKey' ;
20
20
21
21
interface ListParamsOptions {
22
22
resource : string ;
@@ -125,6 +125,7 @@ const useListParams = ({
125
125
: defaultParams ,
126
126
shallowEqual
127
127
) ;
128
+ const tempParams = useRef < ListParams > ( ) ;
128
129
129
130
const requestSignature = [
130
131
location . search ,
@@ -163,21 +164,31 @@ const useListParams = ({
163
164
} , [ ] ) ; // eslint-disable-line
164
165
165
166
const changeParams = useCallback ( action => {
166
- const newParams = queryReducer ( query , action ) ;
167
- if ( syncWithLocation ) {
168
- history . push ( {
169
- search : `?${ stringify ( {
170
- ...newParams ,
171
- filter : JSON . stringify ( newParams . filter ) ,
172
- displayedFilters : JSON . stringify (
173
- newParams . displayedFilters
174
- ) ,
175
- } ) } `,
176
- state : { _scrollToTop : action . type === SET_PAGE } ,
177
- } ) ;
178
- dispatch ( changeListParams ( resource , newParams ) ) ;
167
+ if ( ! tempParams . current ) {
168
+ // no other changeParams action dispatched this tick
169
+ tempParams . current = queryReducer ( query , action ) ;
170
+ // schedule side effects for next tick
171
+ setTimeout ( ( ) => {
172
+ if ( syncWithLocation ) {
173
+ history . push ( {
174
+ search : `?${ stringify ( {
175
+ ...tempParams . current ,
176
+ filter : JSON . stringify ( tempParams . current . filter ) ,
177
+ displayedFilters : JSON . stringify (
178
+ tempParams . current . displayedFilters
179
+ ) ,
180
+ } ) } `,
181
+ state : { _scrollToTop : action . type === SET_PAGE } ,
182
+ } ) ;
183
+ dispatch ( changeListParams ( resource , tempParams . current ) ) ;
184
+ } else {
185
+ setLocalParams ( tempParams . current ) ;
186
+ }
187
+ tempParams . current = undefined ;
188
+ } , 0 ) ;
179
189
} else {
180
- setLocalParams ( newParams ) ;
190
+ // side effects already scheduled, just change the params
191
+ tempParams . current = queryReducer ( tempParams . current , action ) ;
181
192
}
182
193
} , requestSignature ) ; // eslint-disable-line react-hooks/exhaustive-deps
183
194
@@ -229,38 +240,18 @@ const useListParams = ({
229
240
) ;
230
241
231
242
const hideFilter = useCallback ( ( filterName : string ) => {
232
- // we don't use lodash.set() for displayed filters
233
- // to avoid problems with compound filter names (e.g. 'author.name')
234
- const displayedFilters = Object . keys ( displayedFilterValues ) . reduce (
235
- ( filters , filter ) => {
236
- return filter !== filterName
237
- ? { ...filters , [ filter ] : true }
238
- : filters ;
239
- } ,
240
- { }
241
- ) ;
242
- const filter = removeEmpty ( removeKey ( filterValues , filterName ) ) ;
243
243
changeParams ( {
244
- type : SET_FILTER ,
245
- payload : { filter , displayedFilters } ,
244
+ type : HIDE_FILTER ,
245
+ payload : filterName ,
246
246
} ) ;
247
247
} , requestSignature ) ; // eslint-disable-line react-hooks/exhaustive-deps
248
248
249
249
const showFilter = useCallback ( ( filterName : string , defaultValue : any ) => {
250
- // we don't use lodash.set() for displayed filters
251
- // to avoid problems with compound filter names (e.g. 'author.name')
252
- const displayedFilters = {
253
- ...displayedFilterValues ,
254
- [ filterName ] : true ,
255
- } ;
256
- const filter = defaultValue
257
- ? set ( filterValues , filterName , defaultValue )
258
- : filterValues ;
259
250
changeParams ( {
260
- type : SET_FILTER ,
251
+ type : SHOW_FILTER ,
261
252
payload : {
262
- filter ,
263
- displayedFilters ,
253
+ filterName ,
254
+ defaultValue ,
264
255
} ,
265
256
} ) ;
266
257
} , requestSignature ) ; // eslint-disable-line react-hooks/exhaustive-deps
0 commit comments