Skip to content

Commit 2e26339

Browse files
Fix React SRR useLayoutEffect console.error when using CompatRouter (#9820)
1 parent abf222b commit 2e26339

File tree

3 files changed

+43
-1
lines changed

3 files changed

+43
-1
lines changed

contributors.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
- bobziroll
2222
- BrianT1414
2323
- brockross
24+
- brookslybrand
2425
- brophdawg11
2526
- btav
2627
- bvangraafeiland
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* @jest-environment node
3+
*/
4+
import * as React from "react";
5+
import * as ReactDOMServer from "react-dom/server";
6+
import { act } from "react-dom/test-utils";
7+
import { CompatRouter, Routes } from "../index";
8+
9+
// Have to mock react-router-dom to have a comparable API to v5, otherwise it will
10+
// be using v6's API and fail
11+
jest.mock("react-router-dom", () => ({
12+
useHistory: () => ({ location: "/" }),
13+
}));
14+
15+
describe("CompatRouter", () => {
16+
it("should not warn about useLayoutEffect when server side rendering", () => {
17+
const consoleErrorSpy = jest.spyOn(console, "error");
18+
19+
act(() => {
20+
ReactDOMServer.renderToStaticMarkup(
21+
<CompatRouter>
22+
<Routes />
23+
</CompatRouter>
24+
);
25+
});
26+
27+
expect(consoleErrorSpy).toHaveBeenCalledTimes(0);
28+
consoleErrorSpy.mockRestore();
29+
});
30+
});

packages/react-router-dom-v5-compat/lib/components.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,25 @@ export function CompatRoute(props: any) {
2323
);
2424
}
2525

26+
// Copied with 💜 from https://github.com/bvaughn/react-resizable-panels/blob/main/packages/react-resizable-panels/src/hooks/useIsomorphicEffect.ts
27+
const canUseEffectHooks = !!(
28+
typeof window !== "undefined" &&
29+
typeof window.document !== "undefined" &&
30+
typeof window.document.createElement !== "undefined"
31+
);
32+
33+
const useIsomorphicLayoutEffect = canUseEffectHooks
34+
? React.useLayoutEffect
35+
: () => {};
36+
2637
export function CompatRouter({ children }: { children: React.ReactNode }) {
2738
let history = useHistory();
2839
let [state, setState] = React.useState(() => ({
2940
location: history.location,
3041
action: history.action,
3142
}));
3243

33-
React.useLayoutEffect(() => {
44+
useIsomorphicLayoutEffect(() => {
3445
history.listen((location: Location, action: Action) =>
3546
setState({ location, action })
3647
);

0 commit comments

Comments
 (0)