如何向动态加载的React组件传递Ref?
问题解决方法
你遇到的问题核心是动态加载的函数组件需要通过React.forwardRef()正确转发ref,同时要注意@loadable/component传递ref的方式,不能把ref当成普通props传递。下面是具体的修改步骤:
1. 改造动态组件 RecaptchaPackage.tsx
把组件用React.forwardRef()包裹,直接接收ref参数,而非通过forwardedRef props传递:
import React from 'react'; import ReCAPTCHA from 'react-google-recaptcha'; export type RecaptchaPackageProps = { handleOnError: () => void; handleOnExpire: () => void; }; // 使用ForwardRefRenderFunction定义类型,第二个参数为ref const RecaptchaPackage: React.ForwardRefRenderFunction< ReCAPTCHA | null, RecaptchaPackageProps > = ({ handleOnError, handleOnExpire }, ref) => { return process.env.GATSBY_RECAPTCHA_PUBLIC ? ( <ReCAPTCHA onErrored={handleOnError} onExpired={handleOnExpire} ref={ref} // 直接转发ref给ReCAPTCHA组件 sitekey={process.env.GATSBY_RECAPTCHA_PUBLIC} size="invisible" /> ) : null; }; // 结合memo和forwardRef导出组件 export default React.memo(React.forwardRef(RecaptchaPackage));
2. 修改父组件 Recaptcha.tsx
直接给动态加载的组件传递ref属性,不再使用自定义的forwardedRef props:
import React from 'react'; import loadable from '@loadable/component'; import ReCAPTCHA from 'react-google-recaptcha'; // 把loadable定义移到组件外部,避免重复创建组件实例 const RecaptchaPackage = loadable(() => import('components/Form/Recaptcha/RecaptchaPackage')); export type RecaptchaProps = { handleOnError: () => void; handleOnExpire: () => void; error: string | null; load: boolean; forwardedRef: React.MutableRefObject<ReCAPTCHA | null>; }; const Recaptcha: React.FunctionComponent<RecaptchaProps> = ({ handleOnError, handleOnExpire, error, forwardedRef, }) => { return ( <div> <RecaptchaPackage handleOnError={handleOnError} handleOnExpire={handleOnExpire} ref={forwardedRef} // 直接传递ref属性 /> </div> ); }; export default React.memo(Recaptcha);
问题根源
之前你把ref作为普通props(forwardedRef)传递,但函数组件默认不接收ref属性,必须通过React.forwardRef()显式转发。而@loadable/component会正确传递ref给内部组件,只要内部组件是用forwardRef包裹的。
内容的提问来源于stack exchange,提问作者Lewis Carville
相关产品推荐
相关产品推荐

