Skip to content

Commit 22d9b22

Browse files
author
babin
committed
main 🧊 add reactivity for search params hook
1 parent ce8c03d commit 22d9b22

File tree

2 files changed

+39
-7
lines changed

2 files changed

+39
-7
lines changed

‎packages/core/src/bundle/hooks/useUrlSearchParams/useUrlSearchParams.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ export const createQueryString = (searchParams, mode) => {
2424
}
2525
throw new Error('Invalid mode');
2626
};
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));
2730
export const setUrlSearchParams = (mode, params, write = 'replace') => {
2831
const searchParams = new URLSearchParams();
2932
Object.entries(params).forEach(([key, param]) => {
@@ -71,20 +74,31 @@ export const useUrlSearchParams = (initialValue, options = {}) => {
7174
}
7275
return searchParams;
7376
};
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+
});
7587
const set = (params, write = 'replace') => {
7688
const searchParams = setUrlSearchParams(mode, { ...value, ...params }, write ?? writeMode);
7789
setValue(deserializer(searchParams));
90+
dispatchUrlSearchParamsEvent();
7891
};
7992
useEffect(() => {
80-
set(value);
8193
const onParamsChange = () => {
8294
const searchParams = getUrlSearchParams(mode);
83-
set(deserializer(searchParams));
95+
setValue(deserializer(searchParams));
8496
};
97+
window.addEventListener(URL_SEARCH_PARAMS_EVENT, onParamsChange);
8598
window.addEventListener('popstate', onParamsChange);
8699
if (mode !== 'history') window.addEventListener('hashchange', onParamsChange);
87100
return () => {
101+
window.removeEventListener(URL_SEARCH_PARAMS_EVENT, onParamsChange);
88102
window.removeEventListener('popstate', onParamsChange);
89103
if (mode !== 'history') window.removeEventListener('hashchange', onParamsChange);
90104
};

‎packages/core/src/hooks/useUrlSearchParams/useUrlSearchParams.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ export const createQueryString = (searchParams: URLSearchParams, mode: UrlSearch
3535
throw new Error('Invalid mode');
3636
};
3737

38+
export const URL_SEARCH_PARAMS_EVENT = 'reactuse-url-search-params-event';
39+
40+
export const dispatchUrlSearchParamsEvent = () =>
41+
window.dispatchEvent(new Event(URL_SEARCH_PARAMS_EVENT));
42+
3843
export const setUrlSearchParams = <Params extends UrlParams>(
3944
mode: UrlSearchParamsMode,
4045
params: Partial<Params>,
@@ -129,25 +134,38 @@ export const useUrlSearchParams = <
129134
return searchParams;
130135
};
131136

132-
const [value, setValue] = useState(deserializer(initialValue ?? {}) as Params);
137+
const [value, setValue] = useState<Params>(() => {
138+
if (typeof window === 'undefined') return (initialValue ?? {}) as Params;
139+
140+
const searchParams = getUrlSearchParams(mode);
141+
const value = {
142+
...(initialValue && deserializer(initialValue)),
143+
...deserializer(searchParams)
144+
} as Params;
145+
146+
setUrlSearchParams(mode, value, writeMode);
147+
148+
return value;
149+
});
133150

134151
const set = (params: Partial<Params>, write: 'push' | 'replace' = 'replace') => {
135152
const searchParams = setUrlSearchParams(mode, { ...value, ...params }, write ?? writeMode);
136153
setValue(deserializer(searchParams) as Params);
154+
dispatchUrlSearchParamsEvent();
137155
};
138156

139157
useEffect(() => {
140-
set(value);
141-
142158
const onParamsChange = () => {
143159
const searchParams = getUrlSearchParams(mode);
144-
set(deserializer(searchParams) as Params);
160+
setValue(deserializer(searchParams) as Params);
145161
};
146162

163+
window.addEventListener(URL_SEARCH_PARAMS_EVENT, onParamsChange);
147164
window.addEventListener('popstate', onParamsChange);
148165
if (mode !== 'history') window.addEventListener('hashchange', onParamsChange);
149166

150167
return () => {
168+
window.removeEventListener(URL_SEARCH_PARAMS_EVENT, onParamsChange);
151169
window.removeEventListener('popstate', onParamsChange);
152170
if (mode !== 'history') window.removeEventListener('hashchange', onParamsChange);
153171
};

0 commit comments

Comments
 (0)