初始页面加载时React Refs不可用问题求助
问题描述
我需要创建数千个元素,并基于它们的refs执行相关操作。但问题在于初始渲染时所有refs均为undefined,我需要refs在页面初始加载时就可用。点击触发重渲染的按钮后,所有refs都能如预期般正常定义。以下是完整源码:
import { useRef, useState } from "react"; export default function App() { const refs = useRef(new Map()); const [bla, setBla] = useState(0); return ( <> <button onClick={() => setBla((prevState) => prevState + 1)}> click me ({bla}) </button> <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr" }}> <div> {[...Array(100)].map((_, k) => ( <div key={k} ref={(ref) => refs.current.set(k, ref)}> {k} </div> ))} </div> <div> {[...Array(100)].map((_, k) => ( <div key={k}>{refs.current.get(k) ? "defined" : "undefined"}</div> ))} </div> </div> </> ); }
原因分析
这是因为React的ref回调函数是在DOM元素完成挂载后才会触发的。初始渲染时,右侧用来判断refs状态的代码会先于ref回调执行,此时refs的Map里还没有存入任何DOM引用,所以显示全是undefined。点击按钮触发重渲染时,之前的DOM已经挂载完成,ref回调早就执行过了,所以能正确获取到refs。
解决方案
要让初始加载时就能获取到可用的refs,利用useEffect监听组件首次挂载完成的时机即可——useEffect空依赖数组会在组件首次渲染、DOM完全挂载后执行,此时所有ref回调都已经执行完毕,refs里已经存好了所有元素的引用。
如果需要在页面上展示refs的状态,可以加一个状态来控制渲染时机:
import { useRef, useState, useEffect } from "react"; export default function App() { const refs = useRef(new Map()); const [bla, setBla] = useState(0); const [isMounted, setIsMounted] = useState(false); // 组件挂载完成后更新状态,触发重渲染 useEffect(() => { setIsMounted(true); // 这里可以直接写需要用refs执行的逻辑 // 比如遍历refs.current处理所有元素 }, []); return ( <> <button onClick={() => setBla((prevState) => prevState + 1)}> click me ({bla}) </button> <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr" }}> <div> {[...Array(100)].map((_, k) => ( <div key={k} ref={(ref) => refs.current.set(k, ref)}> {k} </div> ))} </div> <div> {/* 等待挂载完成后再渲染判断逻辑 */} {isMounted && [...Array(100)].map((_, k) => ( <div key={k}>{refs.current.get(k) ? "defined" : "undefined"}</div> ))} </div> </div> </> ); }
如果只是需要在初始加载时用refs执行操作,不需要在页面显示状态,直接在useEffect里处理就行,不用额外加isMounted状态。
内容的提问来源于stack exchange,提问作者Page not found
相关产品推荐
相关产品推荐

