React循环渲染元素时创建Ref遇异常,如何修复?
React 数组元素 Ref 创建异常问题
我有一个React元素数组,通过map函数进行渲染:
{ elemsList.map((item, i) => { return ( <div key={i} ref={refsArr[i]} data-grid={item.props["data-grid"]} onClick={e => doubleClickHandler(item.key, e)} style={{ backgroundColor: i === selectedComponent ? '#828EE3' : "#102f6a", color: "#fff", height: "100%", }} > {item} </div> )} ) }
尝试通过useRef创建数组来为每个元素绑定Ref:
const refsArr = useRef([]) refsArr.current = elemsList.map((item, i) => refsArr.current[i] ?? setTimeout(createRef(), 5000)) ... { elemsList.map((item, i) => { return ( <div key={i} ref={refsArr[i]} data-grid={item.props["data-grid"]} onClick={e => doubleClickHandler(item.key, e)} style={{ backgroundColor: i === selectedComponent ? '#828EE3' : "#102f6a", color: "#fff", height: "100%", }} > {item} </div> )} ) }
当前问题:控制台输出Ref数组时,得到的不是正常的Ref对象,而是类似{ current: [53] }的结果,该如何修复?
错误原因分析
setTimeout误用:setTimeout(createRef(), 5000)会立即执行createRef(),并将setTimeout返回的定时器ID(即数字53这类值)赋值给数组项,完全偏离了创建Ref的逻辑。- Ref数组访问错误:
refsArr是useRef返回的对象,真正的数组存储在refsArr.current中,渲染时误用了refsArr[i]而非refsArr.current[i]。 - 初始化逻辑混乱:直接覆盖
refsArr.current的方式会干扰React的Ref绑定机制,导致Ref对象无法正确关联DOM节点。
正确实现方式
方式1:按需初始化Ref数组
import { useRef, useEffect } from 'react'; // ... const refsArr = useRef([]); // 确保Ref数组长度与elemsList匹配,按需创建Ref useEffect(() => { refsArr.current = elemsList.map((_, i) => refsArr.current[i] ?? createRef()); }, [elemsList]); // 渲染部分 {elemsList.map((item, i) => ( <div key={i} ref={refsArr.current[i]} // 正确访问current中的数组项 data-grid={item.props["data-grid"]} onClick={e => doubleClickHandler(item.key, e)} style={{ backgroundColor: i === selectedComponent ? '#828EE3' : "#102f6a", color: "#fff", height: "100%", }} > {item} </div> ))}
方式2:使用回调Ref(更灵活)
无需维护Ref数组的初始化逻辑,直接通过回调将DOM节点存入数组:
const refsArr = useRef([]); // 回调Ref函数,将DOM节点存入数组对应位置 const setRef = (el, index) => { refsArr.current[index] = el; }; // 渲染部分 {elemsList.map((item, i) => ( <div key={i} ref={el => setRef(el, i)} data-grid={item.props["data-grid"]} onClick={e => doubleClickHandler(item.key, e)} style={{ backgroundColor: i === selectedComponent ? '#828EE3' : "#102f6a", color: "#fff", height: "100%", }} > {item} </div> ))}
验证方法
修复后,通过console.log(refsArr.current)即可查看正确的Ref数组,每个数组项都是包含current属性的Ref对象,指向对应的DOM节点。
内容的提问来源于stack exchange,提问作者Listopad02
相关产品推荐
相关产品推荐

