Skip to content

Commit 6c8b1a5

Browse files
committed
fix: 修复 forwardRef 组件的错误无法捕获
1 parent 4684d31 commit 6c8b1a5

3 files changed

Lines changed: 35 additions & 19 deletions

File tree

packages/renderer-core/src/renderer/renderer.tsx

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ import divFactory from '../components/Div';
77
import { IRenderComponent, IRendererProps, IRendererState } from '../types';
88
import { IPublicTypeNodeSchema, IPublicTypeRootSchema } from '@alilc/lowcode-types';
99
import logger from '../utils/logger';
10+
import { cloneEnumerableProperty, isForwardRefType, wrapReactClass } from '@alilc/lowcode-utils';
1011

1112
export default function rendererFactory(): IRenderComponent {
12-
const { PureComponent, Component, createElement, findDOMNode } = adapter.getRuntime();
13+
const { PureComponent, Component, createElement, findDOMNode, forwardRef } = adapter.getRuntime();
1314
const RENDERER_COMPS: any = adapter.getRenderers();
1415
const BaseRenderer = baseRendererFactory();
1516
const AppContext = contextFactory();
@@ -105,18 +106,7 @@ export default function rendererFactory(): IRenderComponent {
105106
return SetComponent;
106107
}
107108

108-
patchDidCatch(SetComponent: any) {
109-
if (!this.isValidComponent(SetComponent)) {
110-
return;
111-
}
112-
if (SetComponent.patchedCatch) {
113-
return;
114-
}
115-
if (!SetComponent.prototype) {
116-
return;
117-
}
118-
SetComponent.patchedCatch = true;
119-
109+
addCatch(SetComponent: any) {
120110
// Rax 的 getDerivedStateFromError 有 BUG,这里先用 componentDidCatch 来替代
121111
// @see https://github.com/alibaba/rax/issues/2211
122112
const originalDidCatch = SetComponent.prototype.componentDidCatch;
@@ -135,12 +125,12 @@ export default function rendererFactory(): IRenderComponent {
135125
return engine.createElement(engine.getFaultComponent(), {
136126
...this.props,
137127
error: this.state.error,
138-
componentName: this.props._componentName
128+
componentName: this.props._componentName,
139129
});
140130
}
141131
return originRender.call(this);
142132
};
143-
if(!(SetComponent.prototype instanceof PureComponent)) {
133+
if (!(SetComponent.prototype instanceof PureComponent)) {
144134
const originShouldComponentUpdate = SetComponent.prototype.shouldComponentUpdate;
145135
SetComponent.prototype.shouldComponentUpdate = function (nextProps: IRendererProps, nextState: any) {
146136
if (nextState && nextState.engineRenderError) {
@@ -151,10 +141,37 @@ export default function rendererFactory(): IRenderComponent {
151141
}
152142
}
153143

144+
patchDidCatch(SetComponent: any) {
145+
if (isForwardRefType(SetComponent)) {
146+
SetComponent.patchedCatch = true;
147+
const Wrapper = wrapReactClass(SetComponent);
148+
this.addCatch(Wrapper);
149+
return cloneEnumerableProperty(
150+
forwardRef((props: any, ref: any) => {
151+
return createElement(Wrapper, { ...props, forwardRef: ref });
152+
}),
153+
SetComponent,
154+
);
155+
}
156+
157+
if (!this.isValidComponent(SetComponent)) {
158+
return;
159+
}
160+
if (SetComponent.patchedCatch) {
161+
return;
162+
}
163+
164+
if (!SetComponent.prototype) {
165+
return;
166+
}
167+
SetComponent.patchedCatch = true;
168+
this.addCatch(SetComponent);
169+
}
170+
154171
createElement(SetComponent: any, props: any, children?: any) {
155172
// TODO: enable in runtime mode?
156-
this.patchDidCatch(SetComponent);
157-
return (this.props.customCreateElement || createElement)(SetComponent, props, children);
173+
const PatchedComponent = this.patchDidCatch(SetComponent) || SetComponent;
174+
return (this.props.customCreateElement || createElement)(PatchedComponent, props, children);
158175
}
159176

160177
getNotFoundComponent() {

packages/renderer-core/src/types/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,6 @@ export interface IRenderComponent {
335335
componentDidCatch(e: any): Promise<void> | void;
336336
shouldComponentUpdate(nextProps: IRendererProps): boolean;
337337
isValidComponent(SetComponent: any): any;
338-
patchDidCatch(SetComponent: any): void;
339338
createElement(SetComponent: any, props: any, children?: any): any;
340339
getNotFoundComponent(): any;
341340
getFaultComponent(): any;

packages/utils/src/is-react.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export function acceptsRef(obj: any): boolean {
1313
return obj?.prototype?.isReactComponent || (obj.$$typeof && obj.$$typeof === REACT_FORWARD_REF_TYPE);
1414
}
1515

16-
function isForwardRefType(obj: any): boolean {
16+
export function isForwardRefType(obj: any): boolean {
1717
return obj?.$$typeof && obj?.$$typeof === REACT_FORWARD_REF_TYPE;
1818
}
1919

0 commit comments

Comments
 (0)