Skip to content

Commit ce3668d

Browse files
committed
withErrorBoundary forwards refs
1 parent e7966d5 commit ce3668d

File tree

2 files changed

+45
-12
lines changed

2 files changed

+45
-12
lines changed

src/withErrorBoundary.test.tsx

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @jest-environment jsdom
33
*/
44

5-
import { PropsWithChildren } from "react";
5+
import { Component, createRef, PropsWithChildren } from "react";
66
import { createRoot } from "react-dom/client";
77
import { act } from "react-dom/test-utils";
88
import { withErrorBoundary } from "./withErrorBoundary";
@@ -53,4 +53,28 @@ describe("withErrorBoundary", () => {
5353
render();
5454
expect(container.textContent).toBe("Error");
5555
});
56+
57+
it("should forward refs", () => {
58+
type Props = { foo: string };
59+
60+
class Inner extends Component<Props> {
61+
test() {}
62+
render() {
63+
return this.props.foo;
64+
}
65+
}
66+
67+
const Wrapped = withErrorBoundary(Inner, {
68+
fallback: <div>Error</div>,
69+
});
70+
71+
const ref = createRef<Inner>();
72+
73+
act(() => {
74+
root.render(<Wrapped foo="abc" ref={ref} />);
75+
});
76+
77+
expect(ref.current).not.toBeNull();
78+
expect(typeof ref.current?.test).toBe("function");
79+
});
5680
});

src/withErrorBoundary.ts

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,30 @@
1-
import { ComponentType, createElement } from "react";
1+
import {
2+
createElement,
3+
forwardRef,
4+
ForwardedRef,
5+
RefAttributes,
6+
ForwardRefExoticComponent,
7+
PropsWithoutRef,
8+
ComponentType,
9+
} from "react";
210
import { ErrorBoundary } from "./ErrorBoundary";
311
import { ErrorBoundaryProps } from "./types";
412

513
export function withErrorBoundary<Props extends Object>(
6-
Component: ComponentType<Props>,
14+
component: ComponentType<Props>,
715
errorBoundaryProps: ErrorBoundaryProps
8-
): ComponentType<Props> {
9-
const Wrapped: ComponentType<Props> = (props: Props) => {
10-
return createElement(
11-
ErrorBoundary,
12-
errorBoundaryProps,
13-
createElement(Component, props)
14-
);
15-
};
16+
): ForwardRefExoticComponent<PropsWithoutRef<Props> & RefAttributes<any>> {
17+
const Wrapped = forwardRef<ComponentType<Props>, Props>(
18+
(props: Props, ref: ForwardedRef<ComponentType<Props>>) =>
19+
createElement(
20+
ErrorBoundary,
21+
errorBoundaryProps,
22+
createElement(component, { ...props, ref })
23+
)
24+
);
1625

1726
// Format for display in DevTools
18-
const name = Component.displayName || Component.name || "Unknown";
27+
const name = component.displayName || component.name || "Unknown";
1928
Wrapped.displayName = `withErrorBoundary(${name})`;
2029

2130
return Wrapped;

0 commit comments

Comments
 (0)