Skip to content

Commit d09d184

Browse files
authored
fix(react): Passes the fallback function through React's createElement function (#10623)
This enables the fallback component used by the React Error Boundary to use hooks.
1 parent 271ab3d commit d09d184

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

packages/react/src/errorboundary.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundarySta
198198
if (state.error) {
199199
let element: React.ReactElement | undefined = undefined;
200200
if (typeof fallback === 'function') {
201-
element = fallback({
201+
element = React.createElement(fallback, {
202202
error: state.error,
203203
componentStack: state.componentStack,
204204
resetError: this.resetErrorBoundary,

packages/react/test/errorboundary.test.tsx

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,20 @@ function Bam(): JSX.Element {
3535
return <Boo title={title} />;
3636
}
3737

38+
function EffectSpyFallback({ error }: { error: Error }): JSX.Element {
39+
const [counter, setCounter] = useState(0);
40+
41+
React.useEffect(() => {
42+
setCounter(c => c + 1);
43+
}, []);
44+
45+
return (
46+
<span>
47+
EffectSpyFallback {counter} - {error.message}
48+
</span>
49+
);
50+
}
51+
3852
interface TestAppProps extends ErrorBoundaryProps {
3953
errorComp?: JSX.Element;
4054
}
@@ -101,7 +115,7 @@ describe('ErrorBoundary', () => {
101115
it('renders null if not given a valid `fallback` prop function', () => {
102116
const { container } = render(
103117
// @ts-expect-error Passing wrong type on purpose
104-
<ErrorBoundary fallback={() => 'Not a ReactElement'}>
118+
<ErrorBoundary fallback={() => undefined}>
105119
<Bam />
106120
</ErrorBoundary>,
107121
);
@@ -118,6 +132,15 @@ describe('ErrorBoundary', () => {
118132
expect(container.innerHTML).toBe('<h1>Error Component</h1>');
119133
});
120134

135+
it('renders a fallback that can use react hooks', () => {
136+
const { container } = render(
137+
<ErrorBoundary fallback={EffectSpyFallback}>
138+
<Bam />
139+
</ErrorBoundary>,
140+
);
141+
expect(container.innerHTML).toBe('<span>EffectSpyFallback 1 - boom</span>');
142+
});
143+
121144
it('calls `onMount` when mounted', () => {
122145
const mockOnMount = jest.fn();
123146
render(

0 commit comments

Comments
 (0)