@@ -24,6 +24,9 @@ export const createQueryString = (searchParams, mode) => {
24
24
}
25
25
throw new Error ( 'Invalid mode' ) ;
26
26
} ;
27
+ export const URL_SEARCH_PARAMS_EVENT = 'reactuse-url-search-params-event' ;
28
+ export const dispatchUrlSearchParamsEvent = ( ) =>
29
+ window . dispatchEvent ( new Event ( URL_SEARCH_PARAMS_EVENT ) ) ;
27
30
export const setUrlSearchParams = ( mode , params , write = 'replace' ) => {
28
31
const searchParams = new URLSearchParams ( ) ;
29
32
Object . entries ( params ) . forEach ( ( [ key , param ] ) => {
@@ -71,20 +74,31 @@ export const useUrlSearchParams = (initialValue, options = {}) => {
71
74
}
72
75
return searchParams ;
73
76
} ;
74
- const [ value , setValue ] = useState ( deserializer ( initialValue ?? { } ) ) ;
77
+ const [ value , setValue ] = useState ( ( ) => {
78
+ if ( typeof window === 'undefined' ) return initialValue ?? { } ;
79
+ const searchParams = getUrlSearchParams ( mode ) ;
80
+ const value = {
81
+ ...( initialValue && deserializer ( initialValue ) ) ,
82
+ ...deserializer ( searchParams )
83
+ } ;
84
+ setUrlSearchParams ( mode , value , writeMode ) ;
85
+ return value ;
86
+ } ) ;
75
87
const set = ( params , write = 'replace' ) => {
76
88
const searchParams = setUrlSearchParams ( mode , { ...value , ...params } , write ?? writeMode ) ;
77
89
setValue ( deserializer ( searchParams ) ) ;
90
+ dispatchUrlSearchParamsEvent ( ) ;
78
91
} ;
79
92
useEffect ( ( ) => {
80
- set ( value ) ;
81
93
const onParamsChange = ( ) => {
82
94
const searchParams = getUrlSearchParams ( mode ) ;
83
- set ( deserializer ( searchParams ) ) ;
95
+ setValue ( deserializer ( searchParams ) ) ;
84
96
} ;
97
+ window . addEventListener ( URL_SEARCH_PARAMS_EVENT , onParamsChange ) ;
85
98
window . addEventListener ( 'popstate' , onParamsChange ) ;
86
99
if ( mode !== 'history' ) window . addEventListener ( 'hashchange' , onParamsChange ) ;
87
100
return ( ) => {
101
+ window . removeEventListener ( URL_SEARCH_PARAMS_EVENT , onParamsChange ) ;
88
102
window . removeEventListener ( 'popstate' , onParamsChange ) ;
89
103
if ( mode !== 'history' ) window . removeEventListener ( 'hashchange' , onParamsChange ) ;
90
104
} ;
0 commit comments