From 53f7b84ebbef6fc699b88f3ef8cc19d35a4e5e58 Mon Sep 17 00:00:00 2001 From: Matt Foster Date: Fri, 9 Feb 2024 11:01:45 -0500 Subject: [PATCH 1/5] Passes the fallback function through React's createElement function. This enables the fallback component to use hooks --- packages/react/src/errorboundary.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/src/errorboundary.tsx b/packages/react/src/errorboundary.tsx index a4920cb37b2b..2fe253883944 100644 --- a/packages/react/src/errorboundary.tsx +++ b/packages/react/src/errorboundary.tsx @@ -197,7 +197,7 @@ class ErrorBoundary extends React.Component Date: Fri, 8 Mar 2024 10:56:57 -0500 Subject: [PATCH 2/5] Adds effect spy to test the fallback's ability to call a hook. Changes a test that was ensuring a function that returned a string would result in a null node. React considers a string to be valid and was creating an element with the string within, changes that function to return undefined instead of a string. --- packages/react/test/errorboundary.test.tsx | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/react/test/errorboundary.test.tsx b/packages/react/test/errorboundary.test.tsx index 09ac96a403dd..527464801f2c 100644 --- a/packages/react/test/errorboundary.test.tsx +++ b/packages/react/test/errorboundary.test.tsx @@ -35,6 +35,14 @@ function Bam(): JSX.Element { return ; } +function EffectSpyFallback({ spy }: { spy: Function}): JSX.Element { + React.useEffect(() => { + spy(); + }) + + return EffectSpyFallback +} + interface TestAppProps extends ErrorBoundaryProps { errorComp?: JSX.Element; } @@ -101,7 +109,7 @@ describe('ErrorBoundary', () => { it('renders null if not given a valid `fallback` prop function', () => { const { container } = render( // @ts-expect-error Passing wrong type on purpose - 'Not a ReactElement'}> + undefined}> , ); @@ -118,6 +126,16 @@ describe('ErrorBoundary', () => { expect(container.innerHTML).toBe('

Error Component

'); }); + it('renders a fallback that can use react hooks', () => { + const spy = jest.fn(); + render( + }> + + , + ); + expect(spy).toHaveBeenCalledTimes(1); + }) + it('calls `onMount` when mounted', () => { const mockOnMount = jest.fn(); render( From 53a7abc249828b7fddfbc7098806b68f895784b9 Mon Sep 17 00:00:00 2001 From: Matt Foster Date: Fri, 8 Mar 2024 11:00:36 -0500 Subject: [PATCH 3/5] Modifies param definition from Function to () => void --- packages/react/test/errorboundary.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/test/errorboundary.test.tsx b/packages/react/test/errorboundary.test.tsx index 527464801f2c..7584f7b842ac 100644 --- a/packages/react/test/errorboundary.test.tsx +++ b/packages/react/test/errorboundary.test.tsx @@ -35,7 +35,7 @@ function Bam(): JSX.Element { return ; } -function EffectSpyFallback({ spy }: { spy: Function}): JSX.Element { +function EffectSpyFallback({ spy }: { spy: () => void}): JSX.Element { React.useEffect(() => { spy(); }) From a0030096be3d7b7efae3c210fe8be9e6b91acb92 Mon Sep 17 00:00:00 2001 From: Matt Foster Date: Fri, 8 Mar 2024 11:33:50 -0500 Subject: [PATCH 4/5] Refactored test to properly exercise correct code flow. --- packages/react/test/errorboundary.test.tsx | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/react/test/errorboundary.test.tsx b/packages/react/test/errorboundary.test.tsx index 7584f7b842ac..85c7d3ca5d15 100644 --- a/packages/react/test/errorboundary.test.tsx +++ b/packages/react/test/errorboundary.test.tsx @@ -35,12 +35,14 @@ function Bam(): JSX.Element { return ; } -function EffectSpyFallback({ spy }: { spy: () => void}): JSX.Element { +function EffectSpyFallback({ error }: { error: Error }): JSX.Element { + const [counter, setCounter] = useState(0); + React.useEffect(() => { - spy(); - }) + setCounter(c => c + 1) + }, []) - return EffectSpyFallback + return EffectSpyFallback {counter} - {error.message} } interface TestAppProps extends ErrorBoundaryProps { @@ -127,13 +129,13 @@ describe('ErrorBoundary', () => { }); it('renders a fallback that can use react hooks', () => { - const spy = jest.fn(); - render( - }> + + const { container } = render( + , ); - expect(spy).toHaveBeenCalledTimes(1); + expect(container.innerHTML).toBe('EffectSpyFallback 1 - boom'); }) it('calls `onMount` when mounted', () => { From 9f8203e7f220afa5f5db1a820d15bacf1f51f60b Mon Sep 17 00:00:00 2001 From: Matt Foster Date: Mon, 11 Mar 2024 15:27:30 -0400 Subject: [PATCH 5/5] Lint fixes --- packages/react/test/errorboundary.test.tsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/react/test/errorboundary.test.tsx b/packages/react/test/errorboundary.test.tsx index 85c7d3ca5d15..7d2526a419ef 100644 --- a/packages/react/test/errorboundary.test.tsx +++ b/packages/react/test/errorboundary.test.tsx @@ -39,10 +39,14 @@ function EffectSpyFallback({ error }: { error: Error }): JSX.Element { const [counter, setCounter] = useState(0); React.useEffect(() => { - setCounter(c => c + 1) - }, []) + setCounter(c => c + 1); + }, []); - return EffectSpyFallback {counter} - {error.message} + return ( + + EffectSpyFallback {counter} - {error.message} + + ); } interface TestAppProps extends ErrorBoundaryProps { @@ -129,14 +133,13 @@ describe('ErrorBoundary', () => { }); it('renders a fallback that can use react hooks', () => { - const { container } = render( , ); expect(container.innerHTML).toBe('EffectSpyFallback 1 - boom'); - }) + }); it('calls `onMount` when mounted', () => { const mockOnMount = jest.fn();