diff --git a/contributors.yml b/contributors.yml index 866b89355d..278c841331 100644 --- a/contributors.yml +++ b/contributors.yml @@ -20,6 +20,7 @@ - bobziroll - BrianT1414 - brockross +- brookslybrand - brophdawg11 - btav - bvangraafeiland diff --git a/packages/react-router-dom-v5-compat/__tests__/compat-router-test.tsx b/packages/react-router-dom-v5-compat/__tests__/compat-router-test.tsx new file mode 100644 index 0000000000..e3b222c5ce --- /dev/null +++ b/packages/react-router-dom-v5-compat/__tests__/compat-router-test.tsx @@ -0,0 +1,30 @@ +/** + * @jest-environment node + */ +import * as React from "react"; +import * as ReactDOMServer from "react-dom/server"; +import { act } from "react-dom/test-utils"; +import { CompatRouter, Routes } from "../index"; + +// Have to mock react-router-dom to have a comparable API to v5, otherwise it will +// be using v6's API and fail +jest.mock("react-router-dom", () => ({ + useHistory: () => ({ location: "/" }), +})); + +describe("CompatRouter", () => { + it("should not warn about useLayoutEffect when server side rendering", () => { + const consoleErrorSpy = jest.spyOn(console, "error"); + + act(() => { + ReactDOMServer.renderToStaticMarkup( + + + + ); + }); + + expect(consoleErrorSpy).toHaveBeenCalledTimes(0); + consoleErrorSpy.mockRestore(); + }); +}); diff --git a/packages/react-router-dom-v5-compat/lib/components.tsx b/packages/react-router-dom-v5-compat/lib/components.tsx index e629beb89b..de8591eb2a 100644 --- a/packages/react-router-dom-v5-compat/lib/components.tsx +++ b/packages/react-router-dom-v5-compat/lib/components.tsx @@ -23,6 +23,17 @@ export function CompatRoute(props: any) { ); } +// Copied with 💜 from https://github.com/bvaughn/react-resizable-panels/blob/main/packages/react-resizable-panels/src/hooks/useIsomorphicEffect.ts +const canUseEffectHooks = !!( + typeof window !== "undefined" && + typeof window.document !== "undefined" && + typeof window.document.createElement !== "undefined" +); + +const useIsomorphicLayoutEffect = canUseEffectHooks + ? React.useLayoutEffect + : () => {}; + export function CompatRouter({ children }: { children: React.ReactNode }) { let history = useHistory(); let [state, setState] = React.useState(() => ({ @@ -30,7 +41,7 @@ export function CompatRouter({ children }: { children: React.ReactNode }) { action: history.action, })); - React.useLayoutEffect(() => { + useIsomorphicLayoutEffect(() => { history.listen((location: Location, action: Action) => setState({ location, action }) );