You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 23:06:09