Skip to content

Commit

Permalink
Merge branch 'release-next'
Browse files Browse the repository at this point in the history
  • Loading branch information
brophdawg11 committed Jun 30, 2023
2 parents fb01a47 + 8be5e51 commit 7178a48
Show file tree
Hide file tree
Showing 16 changed files with 207 additions and 20 deletions.
1 change: 1 addition & 0 deletions contributors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- andreiduca
- antonmontrezor
- appden
- arjunyel
- arnassavickas
- aroyan
- avipatel97
Expand Down
8 changes: 7 additions & 1 deletion docs/hooks/use-submit.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,13 @@ submit([
The default behavior if you submit a JSON object for a POST submission is to encode the data into `FormData`:

```tsx
submit({ key: "value" }, { method: "post" });
submit(
{ key: "value" },
{
method: "post",
encType: "application/x-www-form-urlencoded",
}
);
// will serialize into request.formData() in your action
// and will show up on useNavigation().formData during the navigation
```
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
},
"filesize": {
"packages/router/dist/router.umd.min.js": {
"none": "46.5 kB"
"none": "46.6 kB"
},
"packages/react-router/dist/react-router.production.min.js": {
"none": "13.8 kB"
Expand Down
8 changes: 8 additions & 0 deletions packages/react-router-dom-v5-compat/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# `react-router-dom-v5-compat`

## 6.14.1

### Patch Changes

- Updated dependencies:
- `[email protected]`
- `[email protected]`

## 6.14.0

### Patch Changes
Expand Down
4 changes: 2 additions & 2 deletions packages/react-router-dom-v5-compat/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-router-dom-v5-compat",
"version": "6.14.0",
"version": "6.14.1",
"description": "Migration path to React Router v6 from v4/5",
"keywords": [
"react",
Expand All @@ -24,7 +24,7 @@
"types": "./dist/index.d.ts",
"dependencies": {
"history": "^5.3.0",
"react-router": "6.14.0"
"react-router": "6.14.1"
},
"peerDependencies": {
"react": ">=16.8",
Expand Down
8 changes: 8 additions & 0 deletions packages/react-router-dom/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# `react-router-dom`

## 6.14.1

### Patch Changes

- Updated dependencies:
- `[email protected]`
- `@remix-run/[email protected]`

## 6.14.0

### Minor Changes
Expand Down
115 changes: 115 additions & 0 deletions packages/react-router-dom/__tests__/use-blocker-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,121 @@ describe("navigation blocking with useBlocker", () => {
act(() => root.unmount());
});

it("handles unstable blocker function identities", async () => {
let count = 0;
router = createMemoryRouter([
{
element: React.createElement(() => {
// New function identity on each render
let b = useBlocker(() => false);
blocker = b;
if (++count > 50) {
throw new Error("useBlocker caused a re-render loop!");
}
return (
<div>
<Link to="/about">/about</Link>
<Outlet />
</div>
);
}),
children: [
{
path: "/",
element: <h1>Home</h1>,
},
{
path: "/about",
element: <h1>About</h1>,
},
],
},
]);

act(() => {
root = ReactDOM.createRoot(node);
root.render(<RouterProvider router={router} />);
});

expect(node.querySelector("h1")?.textContent).toBe("Home");

act(() => click(node.querySelector("a[href='/about']")));
expect(node.querySelector("h1")?.textContent).toBe("About");

act(() => root.unmount());
});

it("handles reused blocker in a layout route", async () => {
router = createMemoryRouter([
{
Component() {
let blocker = useBlocker(true);
return (
<div>
<Link to="/one">/one</Link>
<Link to="/two">/two</Link>
<Outlet />
<p>{blocker.state}</p>
{blocker.state === "blocked" ? (
<button onClick={() => blocker.proceed?.()}>Proceed</button>
) : null}
</div>
);
},
children: [
{
path: "/",
element: <h1>Home</h1>,
},
{
path: "/one",
element: <h1>One</h1>,
},
{
path: "/two",
element: <h1>Two</h1>,
},
],
},
]);

act(() => {
root = ReactDOM.createRoot(node);
root.render(<RouterProvider router={router} />);
});

// Start on /
expect(node.querySelector("h1")?.textContent).toBe("Home");
expect(node.querySelector("p")?.textContent).toBe("unblocked");
expect(node.querySelector("button")).toBeNull();

// Blocked navigation to /one
act(() => click(node.querySelector("a[href='/one']")));
expect(node.querySelector("h1")?.textContent).toBe("Home");
expect(node.querySelector("p")?.textContent).toBe("blocked");
expect(node.querySelector("button")?.textContent).toBe("Proceed");

// Proceed to /one
act(() => click(node.querySelector("button")));
expect(node.querySelector("h1")?.textContent).toBe("One");
expect(node.querySelector("p")?.textContent).toBe("unblocked");
expect(node.querySelector("button")).toBeNull();

// Blocked navigation to /two
act(() => click(node.querySelector("a[href='/two']")));
expect(node.querySelector("h1")?.textContent).toBe("One");
expect(node.querySelector("p")?.textContent).toBe("blocked");
expect(node.querySelector("button")?.textContent).toBe("Proceed");

// Proceed to /two
act(() => click(node.querySelector("button")));
expect(node.querySelector("h1")?.textContent).toBe("Two");
expect(node.querySelector("p")?.textContent).toBe("unblocked");
expect(node.querySelector("button")).toBeNull();

act(() => root.unmount());
});

describe("on <Link> navigation", () => {
describe("blocker returns false", () => {
beforeEach(() => {
Expand Down
6 changes: 3 additions & 3 deletions packages/react-router-dom/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-router-dom",
"version": "6.14.0",
"version": "6.14.1",
"description": "Declarative routing for React web applications",
"keywords": [
"react",
Expand All @@ -23,8 +23,8 @@
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"dependencies": {
"@remix-run/router": "1.7.0",
"react-router": "6.14.0"
"@remix-run/router": "1.7.1",
"react-router": "6.14.1"
},
"devDependencies": {
"react": "^18.2.0",
Expand Down
21 changes: 21 additions & 0 deletions packages/react-router-native/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
# `react-router-native`

## 6.14.1

### Patch Changes

- Updated dependencies:
- `[email protected]`

## 6.14.1-pre.1

### Patch Changes

- Updated dependencies:
- `[email protected]`

## 6.14.1-pre.0

### Patch Changes

- Updated dependencies:
- `[email protected]`

## 6.14.0

### Patch Changes
Expand Down
4 changes: 2 additions & 2 deletions packages/react-router-native/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-router-native",
"version": "6.14.0",
"version": "6.14.1",
"description": "Declarative routing for React Native applications",
"keywords": [
"react",
Expand All @@ -22,7 +22,7 @@
"types": "./dist/index.d.ts",
"dependencies": {
"@ungap/url-search-params": "^0.1.4",
"react-router": "6.14.0"
"react-router": "6.14.1"
},
"devDependencies": {
"react": "^18.2.0",
Expand Down
9 changes: 9 additions & 0 deletions packages/react-router/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# `react-router`

## 6.14.1

### Patch Changes

- Fix loop in `unstable_useBlocker` when used with an unstable blocker function ([#10652](https://github.com/remix-run/react-router/pull/10652))
- Fix issues with reused blockers on subsequent navigations ([#10656](https://github.com/remix-run/react-router/pull/10656))
- Updated dependencies:
- `@remix-run/[email protected]`

## 6.14.0

### Patch Changes
Expand Down
22 changes: 16 additions & 6 deletions packages/react-router/lib/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -939,7 +939,6 @@ export function useBlocker(shouldBlock: boolean | BlockerFunction): Blocker {
let state = useDataRouterState(DataRouterStateHook.UseBlocker);

let [blockerKey, setBlockerKey] = React.useState("");
let [blocker, setBlocker] = React.useState<Blocker>(IDLE_BLOCKER);
let blockerFunction = React.useCallback<BlockerFunction>(
(arg) => {
if (typeof shouldBlock !== "function") {
Expand Down Expand Up @@ -972,18 +971,29 @@ export function useBlocker(shouldBlock: boolean | BlockerFunction): Blocker {
[basename, shouldBlock]
);

// This effect is in charge of blocker key assignment and deletion (which is
// tightly coupled to the key)
React.useEffect(() => {
let key = String(++blockerId);
setBlocker(router.getBlocker(key, blockerFunction));
setBlockerKey(key);
return () => router.deleteBlocker(key);
}, [router, setBlocker, setBlockerKey, blockerFunction]);
}, [router]);

// Prefer the blocker from state since DataRouterContext is memoized so this
// ensures we update on blocker state updates
// This effect handles assigning the blockerFunction. This is to handle
// unstable blocker function identities, and happens only after the prior
// effect so we don't get an orphaned blockerFunction in the router with a
// key of "". Until then we just have the IDLE_BLOCKER.
React.useEffect(() => {
if (blockerKey !== "") {
router.getBlocker(blockerKey, blockerFunction);
}
}, [router, blockerKey, blockerFunction]);

// Prefer the blocker from `state` not `router.state` since DataRouterContext
// is memoized so this ensures we update on blocker state updates
return blockerKey && state.blockers.has(blockerKey)
? state.blockers.get(blockerKey)!
: blocker;
: IDLE_BLOCKER;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions packages/react-router/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-router",
"version": "6.14.0",
"version": "6.14.1",
"description": "Declarative routing for React",
"keywords": [
"react",
Expand All @@ -23,7 +23,7 @@
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"dependencies": {
"@remix-run/router": "1.7.0"
"@remix-run/router": "1.7.1"
},
"devDependencies": {
"react": "^18.2.0"
Expand Down
6 changes: 6 additions & 0 deletions packages/router/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# `@remix-run/router`

## 1.7.1

### Patch Changes

- Fix issues with reused blockers on subsequent navigations ([#10656](https://github.com/remix-run/react-router/pull/10656))

## 1.7.0

### Minor Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/router/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@remix-run/router",
"version": "1.7.0",
"version": "1.7.1",
"description": "Nested/Data-driven/Framework-agnostic Routing",
"keywords": [
"remix",
Expand Down
7 changes: 5 additions & 2 deletions packages/router/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1026,8 +1026,11 @@ export function createRouter(init: RouterInit): Router {

// On a successful navigation we can assume we got through all blockers
// so we can start fresh
let blockers = new Map();
blockerFunctions.clear();
let blockers = state.blockers;
if (blockers.size > 0) {
blockers = new Map(blockers);
blockers.forEach((_, k) => blockers.set(k, IDLE_BLOCKER));
}

// Always respect the user flag. Otherwise don't reset on mutation
// submission navigations unless they redirect
Expand Down

0 comments on commit 7178a48

Please sign in to comment.