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

ReactJS中为何无法引用声明的ref?出现myRef未定义报错如何解决

报错原因

  • myRef是StreamingCaptionViewer组件内部声明的局部变量,定义在组件外部的displayTranscription函数不属于组件作用域,按照JS作用域访问规则,自然无法读取到组件内的myRef变量。
  • 现有逻辑存在顺序问题:你调用displayTranscription的目的是生成<p>标签要渲染的新文本,但你在函数内部就尝试读取myRef.current.text,此时新文本还没渲染到<p>标签上,拿到的只会是上一次渲染的旧内容,完全不需要通过读ref的方式拿已有文本。

修复方案

把displayTranscription移到组件内部,同时把全局的totalText改成组件内部的ref存储,避免全局变量污染,也符合React的状态管理规则:

import { createRef, useState, useRef } from 'react';

const StreamingCaptionViewer = () => {
  const myRef = createRef(null);
  // 用useRef存储累计文本,避免组件重渲染时被重置
  const totalTextRef = useRef('');
  const [transcript, setTranscript] = useState(null);
  
  // 函数移到组件内部后就可以正常访问内部的ref和状态
  const displayTranscription = (transcript) => {
    // 先生成本次返回的转录文本
    const currentTranscript = transcript.elements.reduce((a, b) => {
      a += ` ${b.value}`;
      return a;
    }, '');
    // 直接拼接累计文本即可,不需要读取p标签的内容
    totalTextRef.current = totalTextRef.current + currentTranscript;
    console.log('displayTranscript called');
    // 如需渲染累计的全部内容,直接返回totalTextRef.current即可
    return currentTranscript;
  };

  const socket = useSocket('transcript', (data) => {
    console.log(`data recieved: ${JSON.stringify(data)}`);
    setTranscript(data);
  });

  const ErrorMessage = {
    color: 'red',
    fontSize: '13px',
  };

  return (
    <div className='w-full'>
      <p ref={myRef} style={ErrorMessage}>
        {transcript ? displayTranscription(transcript) : null}
      </p>
    </div>
  );
};

如果确实有特殊需求要在组件外部定义该函数,可以把myRef和累计文本作为参数传入函数:

// 新增参数接收所需变量
const displayTranscription = (transcript, existText) => {
  const currentTranscript = transcript.elements.reduce((a, b) => {
    a += ` ${b.value}`;
    return a;
  }, '');
  console.log('dispalyTranscript called');
  // 返回拼接后的全量文本
  return existText + currentTranscript;
};

const StreamingCaptionViewer = () => {
  const myRef = createRef(null);
  const [transcript, setTranscript] = useState(null);
  const [totalText, setTotalText] = useState('');

  const socket = useSocket('transcript', (data) => {
    console.log(`data recieved: ${JSON.stringify(data)}`);
    setTranscript(data);
  });

  const ErrorMessage = {
    color: 'red',
    fontSize: '13px',
  };

  return (
    <div className='w-full'>
      <p ref={myRef} style={ErrorMessage}>
        {transcript ? displayTranscription(transcript, totalText) : null}
      </p>
    </div>
  );
};

内容的提问来源于stack exchange,提问作者jdog

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 20:39:04