From 8fdc5dcc99cfecf56d8b2660a2519d27c16702c5 Mon Sep 17 00:00:00 2001 From: Jonas Kinnvall Date: Mon, 31 Oct 2022 20:23:10 +0100 Subject: [PATCH 1/4] feat: add test to reproduce #605 From 236b99d76e01752c261622cd2b90e7f84e34ba46 Mon Sep 17 00:00:00 2001 From: Jonas Kinnvall Date: Sun, 6 Nov 2022 10:33:22 +0100 Subject: [PATCH 2/4] feat: add ssr test to repro #605 --- src/server/__tests__/ssr.test.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/server/__tests__/ssr.test.ts diff --git a/src/server/__tests__/ssr.test.ts b/src/server/__tests__/ssr.test.ts new file mode 100644 index 00000000..d647bf0e --- /dev/null +++ b/src/server/__tests__/ssr.test.ts @@ -0,0 +1,19 @@ +/** + * @jest-environment node + */ +import { useState } from 'react' +import { renderHook, act } from '..' + +// This verifies that renderHook can be called in +// a SSR-like environment. +describe('renderHook', () => { + function useLoading() { + if (typeof window !== undefined) { + const [loading, setLoading] = useState(false) + return { loading, setLoading } + } + } + test('should not throw in SSR environment', () => { + expect(() => renderHook(() => useLoading())).not.toThrowError('document is not defined') + }) +}) From 25d952117daa8dacc32b1b52af6960f1d568d0e0 Mon Sep 17 00:00:00 2001 From: Jonas Kinnvall Date: Sun, 6 Nov 2022 10:49:04 +0100 Subject: [PATCH 3/4] refactor(server/pure): create hydrate container on client --- src/server/pure.ts | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/server/pure.ts b/src/server/pure.ts index 1bacd008..a98ec90a 100644 --- a/src/server/pure.ts +++ b/src/server/pure.ts @@ -2,7 +2,7 @@ import ReactDOMServer from 'react-dom/server' import ReactDOM from 'react-dom' import { act } from 'react-dom/test-utils' -import { RendererProps, RendererOptions } from '../types/react' +import { RendererOptions, RendererProps } from '../types/react' import { createRenderHook } from '../core' import { createTestHarness } from '../helpers/createTestHarness' @@ -12,8 +12,8 @@ function createServerRenderer( { wrapper }: RendererOptions ) { let renderProps: TProps | undefined - let hydrated = false - const container = document.createElement('div') + let container: HTMLDivElement | undefined + let serverOutput: string = '' const testHarness = createTestHarness(rendererProps, wrapper, false) return { @@ -21,35 +21,34 @@ function createServerRenderer( renderProps = props act(() => { try { - const serverOutput = ReactDOMServer.renderToString(testHarness(props)) - container.innerHTML = serverOutput + serverOutput = ReactDOMServer.renderToString(testHarness(props)) } catch (e: unknown) { rendererProps.setError(e as Error) } }) }, hydrate() { - if (hydrated) { + if (container) { throw new Error('The component can only be hydrated once') } else { + container.innerHTML = serverOutput act(() => { - ReactDOM.hydrate(testHarness(renderProps), container) + ReactDOM.hydrate(testHarness(renderProps), container!) }) - hydrated = true } }, rerender(props?: TProps) { - if (!hydrated) { + if (!container) { throw new Error('You must hydrate the component before you can rerender') } act(() => { - ReactDOM.render(testHarness(props), container) + ReactDOM.render(testHarness(props), container!) }) }, unmount() { - if (hydrated) { + if (container) { act(() => { - ReactDOM.unmountComponentAtNode(container) + ReactDOM.unmountComponentAtNode(container!) }) } }, From ce08e581970dedfdffacc7b1a65de3f23f103e7e Mon Sep 17 00:00:00 2001 From: Jonas Kinnvall Date: Sun, 6 Nov 2022 10:56:33 +0100 Subject: [PATCH 4/4] refactor: improve type-safety in src/server/pure --- src/server/pure.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/server/pure.ts b/src/server/pure.ts index a98ec90a..2b0de89a 100644 --- a/src/server/pure.ts +++ b/src/server/pure.ts @@ -13,7 +13,7 @@ function createServerRenderer( ) { let renderProps: TProps | undefined let container: HTMLDivElement | undefined - let serverOutput: string = '' + let serverOutput = '' const testHarness = createTestHarness(rendererProps, wrapper, false) return { @@ -33,7 +33,7 @@ function createServerRenderer( } else { container.innerHTML = serverOutput act(() => { - ReactDOM.hydrate(testHarness(renderProps), container!) + ReactDOM.hydrate(testHarness(renderProps), container || null) }) } }, @@ -42,13 +42,15 @@ function createServerRenderer( throw new Error('You must hydrate the component before you can rerender') } act(() => { - ReactDOM.render(testHarness(props), container!) + ReactDOM.render(testHarness(props), container || null) }) }, unmount() { if (container) { act(() => { - ReactDOM.unmountComponentAtNode(container!) + if (typeof container !== 'undefined') { + ReactDOM.unmountComponentAtNode(container) + } }) } },