File tree Expand file tree Collapse file tree 3 files changed +50
-7
lines changed
packages/react-router-dom Expand file tree Collapse file tree 3 files changed +50
-7
lines changed Original file line number Diff line number Diff line change @@ -125,4 +125,40 @@ describe("useSearchParams", () => {
125
125
) ;
126
126
expect ( node . innerHTML ) . toMatch ( / T h e n e w q u e r y i s " R y a n F l o r e n c e " / ) ;
127
127
} ) ;
128
+
129
+ it ( "allows removal of search params when a default is provided" , ( ) => {
130
+ function SearchPage ( ) {
131
+ let [ searchParams , setSearchParams ] = useSearchParams ( {
132
+ value : "initial" ,
133
+ } ) ;
134
+
135
+ return (
136
+ < div >
137
+ < p > The current value is "{ searchParams . get ( "value" ) } ".</ p >
138
+ < button onClick = { ( ) => setSearchParams ( { } ) } > Click</ button >
139
+ </ div >
140
+ ) ;
141
+ }
142
+
143
+ act ( ( ) => {
144
+ ReactDOM . createRoot ( node ) . render (
145
+ < MemoryRouter initialEntries = { [ "/search?value=initial" ] } >
146
+ < Routes >
147
+ < Route path = "search" element = { < SearchPage /> } />
148
+ </ Routes >
149
+ </ MemoryRouter >
150
+ ) ;
151
+ } ) ;
152
+
153
+ let button = node . querySelector < HTMLInputElement > ( "button" ) ! ;
154
+ expect ( button ) . toBeDefined ( ) ;
155
+
156
+ expect ( node . innerHTML ) . toMatch ( / T h e c u r r e n t v a l u e i s " i n i t i a l " / ) ;
157
+
158
+ act ( ( ) => {
159
+ button . dispatchEvent ( new Event ( "click" , { bubbles : true } ) ) ;
160
+ } ) ;
161
+
162
+ expect ( node . innerHTML ) . toMatch ( / T h e c u r r e n t v a l u e i s " " / ) ;
163
+ } ) ;
128
164
} ) ;
Original file line number Diff line number Diff line change @@ -88,15 +88,17 @@ export function createSearchParams(
88
88
89
89
export function getSearchParamsForLocation (
90
90
locationSearch : string ,
91
- defaultSearchParams : URLSearchParams
91
+ defaultSearchParams : URLSearchParams | null
92
92
) {
93
93
let searchParams = createSearchParams ( locationSearch ) ;
94
94
95
- for ( let key of defaultSearchParams . keys ( ) ) {
96
- if ( ! searchParams . has ( key ) ) {
97
- defaultSearchParams . getAll ( key ) . forEach ( ( value ) => {
98
- searchParams . append ( key , value ) ;
99
- } ) ;
95
+ if ( defaultSearchParams ) {
96
+ for ( let key of defaultSearchParams . keys ( ) ) {
97
+ if ( ! searchParams . has ( key ) ) {
98
+ defaultSearchParams . getAll ( key ) . forEach ( ( value ) => {
99
+ searchParams . append ( key , value ) ;
100
+ } ) ;
101
+ }
100
102
}
101
103
}
102
104
Original file line number Diff line number Diff line change @@ -853,13 +853,17 @@ export function useSearchParams(
853
853
) ;
854
854
855
855
let defaultSearchParamsRef = React . useRef ( createSearchParams ( defaultInit ) ) ;
856
+ let hasSetSearchParamsRef = React . useRef ( false ) ;
856
857
857
858
let location = useLocation ( ) ;
858
859
let searchParams = React . useMemo (
859
860
( ) =>
861
+ // Only merge in the defaults if we haven't yet called setSearchParams.
862
+ // Once we call that we want those to take precedence, otherwise you can't
863
+ // remove a param with setSearchParams({}) if it has an initial value
860
864
getSearchParamsForLocation (
861
865
location . search ,
862
- defaultSearchParamsRef . current
866
+ hasSetSearchParamsRef . current ? null : defaultSearchParamsRef . current
863
867
) ,
864
868
[ location . search ]
865
869
) ;
@@ -870,6 +874,7 @@ export function useSearchParams(
870
874
const newSearchParams = createSearchParams (
871
875
typeof nextInit === "function" ? nextInit ( searchParams ) : nextInit
872
876
) ;
877
+ hasSetSearchParamsRef . current = true ;
873
878
navigate ( "?" + newSearchParams , navigateOptions ) ;
874
879
} ,
875
880
[ navigate , searchParams ]
You can’t perform that action at this time.
0 commit comments