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
相关产品推荐
相关产品推荐

