@@ -7,9 +7,10 @@ import divFactory from '../components/Div';
77import { IRenderComponent , IRendererProps , IRendererState } from '../types' ;
88import { IPublicTypeNodeSchema , IPublicTypeRootSchema } from '@alilc/lowcode-types' ;
99import logger from '../utils/logger' ;
10+ import { cloneEnumerableProperty , isForwardRefType , wrapReactClass } from '@alilc/lowcode-utils' ;
1011
1112export 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 ( ) {
0 commit comments