Skip to content

Commit 7f9453c

Browse files
committed
Merge branch 'release-changesets' into changesets
2 parents 2b9cd64 + 8fa531e commit 7f9453c

File tree

25 files changed

+463
-77
lines changed

25 files changed

+463
-77
lines changed

.changeset/eighty-forks-search.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"react-router": patch
3+
"react-router-dom": patch
4+
---
5+
6+
Fix broken require for CJS builds

contributors.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@
2323
- hyesungoh
2424
- IbraRouisDev
2525
- Isammoc
26+
- JaffParker
2627
- JakubDrozd
2728
- janpaepke
2829
- jimniels
2930
- jmargeta
31+
- johnpangalos
3032
- jonkoops
3133
- kantuni
3234
- kddnewton
@@ -48,6 +50,7 @@
4850
- noisypigeon
4951
- paulsmithkc
5052
- petersendidit
53+
- promet99
5154
- RobHannay
5255
- rtmann
5356
- ryanflorence
@@ -65,6 +68,5 @@
6568
- turansky
6669
- underager
6770
- vijaypushkin
68-
- rtmann
69-
- williamsdyyz
7071
- vikingviolinist
72+
- williamsdyyz

docs/hooks/use-search-params-rn.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,22 @@ type URLSearchParamsInit =
2626
| URLSearchParams;
2727

2828
type SetURLSearchParams = (
29-
nextInit?: URLSearchParamsInit,
29+
nextInit?:
30+
| URLSearchParamsInit
31+
| ((prev: URLSearchParams) => URLSearchParamsInit),
3032
navigateOpts?: : NavigateOptions
3133
) => void;
3234

3335
interface NavigateOptions {
3436
replace?: boolean;
3537
state?: any;
38+
resetScroll?: boolean;
3639
}
3740
```
3841

3942
</details>
4043

41-
The `useSearchParams` hook is used to read and modify the query string in the URL for the current location. Like React's own [`useState` hook](https://reactjs.org/docs/hooks-reference.html#usestate), `useSearchParams` returns an array of two values: the current location's [search params](https://developer.mozilla.org/en-US/docs/Web/API/URL/searchParams) and a function that may be used to update them.
44+
The `useSearchParams` hook is used to read and modify the query string in the URL for the current location. Like React's own [`useState` hook][usestate], `useSearchParams` returns an array of two values: the current location's [search params][searchparams] and a function that may be used to update them. Just as React's [`useState` hook][usestate], `setSearchParams` also supports [functional updates][functional-updates]. Therefore, you may provide a function that takes a `searchParams` and returns an updated version.
4245

4346
```tsx
4447
import * as React from "react";
@@ -65,4 +68,7 @@ function App() {
6568
}
6669
```
6770

71+
[functional-updates]: https://reactjs.org/docs/hooks-reference.html#functional-updates
72+
[searchparams]: https://developer.mozilla.org/en-US/docs/Web/API/URL/searchParams
6873
[usesearchparams]: ./use-search-params.md
74+
[usestate]: https://reactjs.org/docs/hooks-reference.html#usestate

docs/hooks/use-search-params.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,22 @@ type URLSearchParamsInit =
2626
| URLSearchParams;
2727

2828
type SetURLSearchParams = (
29-
nextInit?: URLSearchParamsInit,
30-
navigateOpts?: : { replace?: boolean; state?: any }
29+
nextInit?:
30+
| URLSearchParamsInit
31+
| ((prev: URLSearchParams) => URLSearchParamsInit),
32+
navigateOpts?: : NavigateOptions
3133
) => void;
34+
35+
interface NavigateOptions {
36+
replace?: boolean;
37+
state?: any;
38+
resetScroll?: boolean;
39+
}
3240
```
3341

3442
</details>
3543

36-
The `useSearchParams` hook is used to read and modify the query string in the URL for the current location. Like React's own [`useState` hook](https://reactjs.org/docs/hooks-reference.html#usestate), `useSearchParams` returns an array of two values: the current location's [search params](https://developer.mozilla.org/en-US/docs/Web/API/URL/searchParams) and a function that may be used to update them.
44+
The `useSearchParams` hook is used to read and modify the query string in the URL for the current location. Like React's own [`useState` hook][usestate], `useSearchParams` returns an array of two values: the current location's [search params][searchparams] and a function that may be used to update them. Just as React's [`useState` hook][usestate], `setSearchParams` also supports [functional updates][functional-updates]. Therefore, you may provide a function that takes a `searchParams` and returns an updated version.
3745

3846
```tsx
3947
import * as React from "react";
@@ -66,5 +74,8 @@ function App() {
6674
> of the URL. Also note that the second arg to `setSearchParams` is
6775
> the same type as the second arg to `navigate`.
6876
77+
[functional-updates]: https://reactjs.org/docs/hooks-reference.html#functional-updates
78+
[searchparams]: https://developer.mozilla.org/en-US/docs/Web/API/URL/searchParams
6979
[usesearchparams-native]: ./use-search-params-rn
80+
[usestate]: https://reactjs.org/docs/hooks-reference.html#usestate
7081
[usenavigate]: ./use-navigate

packages/react-router-dom-v5-compat/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# react-router-dom-v5-compat
22

3+
## 6.4.0-pre.4
4+
5+
### Patch Changes
6+
7+
- Fix missing `dist` files
8+
39
## 6.4.0-pre.3
410

511
### Patch Changes

packages/react-router-dom-v5-compat/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export type {
5858
Navigator,
5959
OutletProps,
6060
Params,
61+
ParamParseKey,
6162
PathMatch,
6263
RouteMatch,
6364
RouteObject,

packages/react-router-dom-v5-compat/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-router-dom-v5-compat",
3-
"version": "6.4.0-pre.3",
3+
"version": "6.4.0-pre.4",
44
"description": "Migration path to React Router v6 from v4/5",
55
"keywords": [
66
"react",
@@ -24,12 +24,12 @@
2424
"types": "./dist/index.d.ts",
2525
"dependencies": {
2626
"history": "^5.3.0",
27-
"react-router": "6.4.0-pre.3"
27+
"react-router": "6.4.0-pre.4"
2828
},
2929
"peerDependencies": {
3030
"react": ">=16.8",
3131
"react-dom": ">=16.8",
32-
"react-router-dom": "6.4.0-pre.3"
32+
"react-router-dom": "6.4.0-pre.4"
3333
},
3434
"files": [
3535
"dist/",

packages/react-router-dom/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# react-router-dom
22

3+
## 6.4.0-pre.4
4+
5+
### Patch Changes
6+
7+
- Fix missing `dist` files
8+
39
## 6.4.0-pre.3
410

511
### Patch Changes

packages/react-router-dom/__tests__/search-params-test.tsx

Lines changed: 83 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,6 @@ import { act } from "react-dom/test-utils";
44
import { MemoryRouter, Routes, Route, useSearchParams } from "react-router-dom";
55

66
describe("useSearchParams", () => {
7-
function SearchPage() {
8-
let queryRef = React.useRef<HTMLInputElement>(null);
9-
let [searchParams, setSearchParams] = useSearchParams({ q: "" });
10-
let query = searchParams.get("q")!;
11-
12-
function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
13-
event.preventDefault();
14-
if (queryRef.current) {
15-
setSearchParams({ q: queryRef.current.value });
16-
}
17-
}
18-
19-
return (
20-
<div>
21-
<p>The current query is "{query}".</p>
22-
<form onSubmit={handleSubmit}>
23-
<input name="q" defaultValue={query} ref={queryRef} />
24-
</form>
25-
</div>
26-
);
27-
}
28-
297
let node: HTMLDivElement;
308
beforeEach(() => {
319
node = document.createElement("div");
@@ -38,6 +16,28 @@ describe("useSearchParams", () => {
3816
});
3917

4018
it("reads and writes the search string", () => {
19+
function SearchPage() {
20+
let queryRef = React.useRef<HTMLInputElement>(null);
21+
let [searchParams, setSearchParams] = useSearchParams({ q: "" });
22+
let query = searchParams.get("q")!;
23+
24+
function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
25+
event.preventDefault();
26+
if (queryRef.current) {
27+
setSearchParams({ q: queryRef.current.value });
28+
}
29+
}
30+
31+
return (
32+
<div>
33+
<p>The current query is "{query}".</p>
34+
<form onSubmit={handleSubmit}>
35+
<input name="q" defaultValue={query} ref={queryRef} />
36+
</form>
37+
</div>
38+
);
39+
}
40+
4141
act(() => {
4242
ReactDOM.render(
4343
<MemoryRouter initialEntries={["/search?q=Michael+Jackson"]}>
@@ -66,4 +66,65 @@ describe("useSearchParams", () => {
6666

6767
expect(node.innerHTML).toMatch(/The current query is "Ryan Florence"/);
6868
});
69+
70+
it("updates searchParams when a function is provided to setSearchParams (functional updates)", () => {
71+
function SearchPage() {
72+
let queryRef = React.useRef<HTMLInputElement>(null);
73+
let [searchParams, setSearchParams] = useSearchParams({ q: "" });
74+
let query = searchParams.get("q")!;
75+
let queryNew = searchParams.get("new")!;
76+
77+
function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
78+
event.preventDefault();
79+
if (queryRef.current) {
80+
setSearchParams((cur) => {
81+
cur.set("q", `${cur.get("q")} - appended`);
82+
cur.set("new", "Ryan Florence");
83+
return cur;
84+
});
85+
}
86+
}
87+
88+
return (
89+
<div>
90+
<p>The current query is "{query}".</p>
91+
<p>The new query is "{queryNew}"</p>
92+
<form onSubmit={handleSubmit}>
93+
<input name="q" defaultValue={query} ref={queryRef} />
94+
</form>
95+
</div>
96+
);
97+
}
98+
99+
act(() => {
100+
ReactDOM.render(
101+
<MemoryRouter initialEntries={["/search?q=Michael+Jackson"]}>
102+
<Routes>
103+
<Route path="search" element={<SearchPage />} />
104+
</Routes>
105+
</MemoryRouter>,
106+
node
107+
);
108+
});
109+
110+
let form = node.querySelector("form")!;
111+
expect(form).toBeDefined();
112+
113+
let queryInput = node.querySelector<HTMLInputElement>("input[name=q]")!;
114+
expect(queryInput).toBeDefined();
115+
116+
expect(node.innerHTML).toMatch(/The current query is "Michael Jackson"/);
117+
expect(node.innerHTML).toMatch(/The new query is ""/);
118+
119+
act(() => {
120+
form.dispatchEvent(
121+
new Event("submit", { bubbles: true, cancelable: true })
122+
);
123+
});
124+
125+
expect(node.innerHTML).toMatch(
126+
/The current query is "Michael Jackson - appended"/
127+
);
128+
expect(node.innerHTML).toMatch(/The new query is "Ryan Florence"/);
129+
});
69130
});

packages/react-router-dom/index.tsx

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* you'll need to update the rollup config for react-router-dom-v5-compat.
44
*/
55
import * as React from "react";
6+
import type { NavigateOptions, To } from "react-router";
67
import {
78
Router,
89
createPath,
@@ -16,16 +17,15 @@ import {
1617
UNSAFE_DataRouterContext,
1718
UNSAFE_DataRouterStateContext,
1819
} from "react-router";
19-
import type { To } from "react-router";
2020
import type {
2121
BrowserHistory,
2222
Fetcher,
2323
FormEncType,
2424
FormMethod,
25+
GetScrollRestorationKeyFunction,
2526
HashHistory,
2627
History,
2728
HydrationState,
28-
GetScrollRestorationKeyFunction,
2929
RouteObject,
3030
} from "@remix-run/router";
3131
import {
@@ -77,6 +77,7 @@ export type {
7777
Navigator,
7878
OutletProps,
7979
Params,
80+
ParamParseKey,
8081
Path,
8182
PathMatch,
8283
Pathname,
@@ -658,7 +659,9 @@ export function useLinkClickHandler<E extends Element = HTMLAnchorElement>(
658659
* A convenient wrapper for reading and writing search parameters via the
659660
* URLSearchParams interface.
660661
*/
661-
export function useSearchParams(defaultInit?: URLSearchParamsInit) {
662+
export function useSearchParams(
663+
defaultInit?: URLSearchParamsInit
664+
): [URLSearchParams, SetURLSearchParams] {
662665
warning(
663666
typeof URLSearchParams !== "undefined",
664667
`You cannot use the \`useSearchParams\` hook in a browser that does not ` +
@@ -684,19 +687,26 @@ export function useSearchParams(defaultInit?: URLSearchParamsInit) {
684687
);
685688

686689
let navigate = useNavigate();
687-
let setSearchParams = React.useCallback(
688-
(
689-
nextInit: URLSearchParamsInit,
690-
navigateOptions?: { replace?: boolean; state?: any }
691-
) => {
692-
navigate("?" + createSearchParams(nextInit), navigateOptions);
690+
let setSearchParams = React.useCallback<SetURLSearchParams>(
691+
(nextInit, navigateOptions) => {
692+
const newSearchParams = createSearchParams(
693+
typeof nextInit === "function" ? nextInit(searchParams) : nextInit
694+
);
695+
navigate("?" + newSearchParams, navigateOptions);
693696
},
694-
[navigate]
697+
[navigate, searchParams]
695698
);
696699

697-
return [searchParams, setSearchParams] as const;
700+
return [searchParams, setSearchParams];
698701
}
699702

703+
type SetURLSearchParams = (
704+
nextInit?:
705+
| URLSearchParamsInit
706+
| ((prev: URLSearchParams) => URLSearchParamsInit),
707+
navigateOpts?: NavigateOptions
708+
) => void;
709+
700710
/**
701711
* Submits a HTML `<form>` to the server without reloading the page.
702712
*/

0 commit comments

Comments
 (0)