React新手使用useImperativeHandle报错:sayHi不是函数,求排查语法问题
问题分析与修复
你的代码有两个核心问题导致了sayHi不是函数的错误:
1. 父组件中ref的初始化错误
父组件里你给useRef传入了字符串初始值:
const refs = useRef("HELLO World");
但通过forwardRef传递给子组件的ref,需要是一个初始值为null的空引用对象,React会在子组件挂载后,把useImperativeHandle暴露的方法挂载到这个ref的current属性上。初始值设为字符串的话,后续无法正确赋值子组件暴露的实例。
2. 调用时机错误:组件未挂载就调用方法
你在父组件的函数体里直接调用sayHello(),这时候组件还没完成渲染,子组件的ref还没被赋值,refs.current仍然是你初始化的字符串,自然没有sayHi方法。必须等组件挂载完成后再调用这个方法,比如用useEffect钩子。
修复后的完整代码
import React, { forwardRef, useRef, useImperativeHandle, useEffect } from 'react' import ReactDOM from 'react-dom/client' const ChildComponent = forwardRef(function reference(props, ref) { const refs = useRef(null); useImperativeHandle(ref, () => { return { sayHi: () => { console.log("hello world"); } } }); return <div ref={refs}>{refs.current}</div>; }); function ParentComponent() { // 初始化为null的空ref const childRef = useRef(null); function sayHello() { // 先判断current是否存在,避免报错 if (childRef.current) { childRef.current.sayHi(); } } // 组件挂载后调用方法 useEffect(() => { sayHello(); }, []); return <ChildComponent ref={childRef} />; } const div_root = ReactDOM.createRoot(document.getElementById("root")); div_root.render(<ParentComponent />);
内容的提问来源于stack exchange,提问作者Onxy_Tzy
相关产品推荐
相关产品推荐

