TypeScript中转发多Ref对象时的类型匹配错误问题
TypeScript中转发多ref对象的类型错误解决方法
问题根源
你在forwardRef中错误地将泛型参数指定为React.MutableRefObject<{...}>,但实际应该直接使用包含多个ref的对象类型;同时父组件对refs的包裹和传递方式也存在类型不匹配问题。
解决方案1:通过forwardRef让父组件获取子组件内的多ref
如果需求是让父组件访问Navbar内部的三个ref,按以下步骤修改:
- 定义类型
// 组件要暴露的ref集合类型 type NavbarExposedRefs = { storyRef: React.RefObject<HTMLElement>; parcoursRef: React.RefObject<HTMLElement>; projectRef: React.RefObject<HTMLElement>; }; // 组件props类型 type ModalProps = { setShowModal: () => void; };
- 编写Navbar组件
const Navbar = React.forwardRef<NavbarExposedRefs, ModalProps>(({ setShowModal }, ref) => { // 组件内部创建三个ref const storyRef = React.useRef<HTMLElement>(null); const parcoursRef = React.useRef<HTMLElement>(null); const projectRef = React.useRef<HTMLElement>(null); // 将内部ref暴露给父组件 React.useImperativeHandle(ref, () => ({ storyRef, parcoursRef, projectRef, }), []); return ( <nav> <div ref={storyRef}>Story区块</div> <div ref={parcoursRef}>Parcours区块</div> <div ref={projectRef}>Project区块</div> <button onClick={setShowModal}>打开弹窗</button> </nav> ); });
- 父组件使用
const navbarRef = React.useRef<NavbarExposedRefs>(null); // 示例:通过ref滚动到指定区块 const scrollToStory = () => { navbarRef.current?.storyRef.current?.scrollIntoView({ behavior: 'smooth' }); }; <Navbar ref={navbarRef} setShowModal={setShowModal} />
解决方案2:将父组件的ref通过props传递给Navbar
如果需求是把父组件已创建的三个ref传给Navbar使用(比如控制滚动),无需使用forwardRef,直接通过props传递更简单:
- 定义props类型
type NavbarProps = ModalProps & { sectionRefs: { storyRef: React.RefObject<HTMLElement>; parcoursRef: React.RefObject<HTMLElement>; projectRef: React.RefObject<HTMLElement>; }; };
- 编写Navbar组件
const Navbar = ({ setShowModal, sectionRefs }: NavbarProps) => { const scrollToSection = (ref: React.RefObject<HTMLElement>) => { ref.current?.scrollIntoView({ behavior: 'smooth' }); }; return ( <nav> <button onClick={() => scrollToSection(sectionRefs.storyRef)}>跳转到Story</button> <button onClick={() => scrollToSection(sectionRefs.parcoursRef)}>跳转到Parcours</button> <button onClick={() => scrollToSection(sectionRefs.projectRef)}>跳转到Project</button> <button onClick={setShowModal}>打开弹窗</button> </nav> ); };
- 父组件使用
const storyRef = React.useRef<HTMLElement>(null); const parcoursRef = React.useRef<HTMLElement>(null); const projectRef = React.useRef<HTMLElement>(null); <Navbar sectionRefs={{ storyRef, parcoursRef, projectRef }} setShowModal={setShowModal} />
原始错误细节解释
你之前在forwardRef的第一个泛型参数中写了React.MutableRefObject<{...}>,导致ref参数的类型要求为Ref<MutableRefObject<{...}>>,但你传递的refs是MutableRefObject<{...}>(其current值是包含三个ref的对象),两者类型不匹配。正确做法是将forwardRef的泛型参数指定为内部的对象类型(即{storyRef: React.RefObject<HTMLElement>; ...}),而非包裹后的MutableRefObject。
内容的提问来源于stack exchange,提问作者samuel potter
相关产品推荐
相关产品推荐

