Next.js中visibility:hidden与useEffect的异常问题排查
问题现象
在Next.js项目中,尝试将组件内两个div的文本拆分为单个span元素时,遇到以下问题:
- 未给父div设置
visibility:hidden时,文本拆分功能正常,DOM结构符合预期 - 添加
visibility:hidden后,两个子div变成空内容,拆分逻辑失效 - 尝试替换为
useLayoutEffect也无改善,且该属性是后续动画效果必需的
相关代码
组件代码
const MyComponent = () => { const splitRef = useRef(null); useEffect(() => { const divs = splitRef.current.querySelectorAll("div"); divs.forEach((item) => { let newInnerText = ""; const letters = item.innerText.split(""); letters.forEach((letter) => { newInnerText += `<span>${letter}</span>`; }); item.innerHTML = newInnerText; }); }, []); return ( <> <div ref={splitRef} style={{ visibility: "hidden" }}> <div>CONTACT</div> <div>ABOUT</div> </div> </> ); };
页面引入代码
export default function IndexPage() { return ( <div> <MyComponent /> </div> ); }
DOM结构对比
- 无visibility:hidden时:
<div> <div> <span>C</span><span>O</span><span>N</span><span>T</span><span>A</span><span>C</span><span>T</span> </div> <div> <span>A</span><span>B</span><span>O</span><span>U</span><span>T</span> </div> </div>
- 添加visibility:hidden后:
<div style="visibility:hidden"> <div></div> <div></div> </div>
问题原因
核心矛盾在于innerText的特性与Next.js的渲染机制:
innerText会受CSS可见性影响,且依赖元素的布局状态。当元素设置visibility:hidden后,在客户端Hydration阶段,浏览器可能因元素不可见而延迟布局计算,导致innerText无法获取到文本内容,最终拆分逻辑得到空数组,将子div的innerHTML设置为空。- 服务端渲染时,虽然初始HTML包含文本,但客户端Hydration时的布局处理逻辑会影响
innerText的取值。
解决方案
将代码中的innerText替换为textContent即可解决问题。textContent直接读取DOM节点的原始文本内容,不受CSS可见性和布局状态的影响,无论元素是否可见都能正确获取文本。
修改后的组件代码
const MyComponent = () => { const splitRef = useRef(null); useEffect(() => { const divs = splitRef.current.querySelectorAll("div"); divs.forEach((item) => { let newInnerText = ""; // 改用textContent获取文本,不受visibility属性影响 const letters = item.textContent.split(""); letters.forEach((letter) => { newInnerText += `<span>${letter}</span>`; }); item.innerHTML = newInnerText; }); }, []); return ( <> <div ref={splitRef} style={{ visibility: "hidden" }}> <div>CONTACT</div> <div>ABOUT</div> </div> </> ); };
修改后,即使父div设置了visibility:hidden,文本拆分逻辑仍能正常工作,DOM结构与无该属性时一致,同时保留后续动画所需的visibility设置。
内容的提问来源于stack exchange,提问作者Nas
相关产品推荐
相关产品推荐

