React中如何通过条件渲染实现元素展开及子元素延迟渲染?
实现方案
可以通过条件渲染+动画结束事件监听来实现你的需求,具体步骤如下:
1. 定义状态控制元素渲染
设置两个状态分别控制两个盒子的渲染时机:
isExpanding:控制黄色盒子的挂载与展开触发showInnerBox:控制蓝色盒子的条件渲染
2. 绑定动画结束事件实现顺序渲染
点击按钮后先挂载黄色盒子,通过CSS过渡实现宽度从0到100px的展开动画;同时监听黄色盒子的transitionend事件,仅当宽度动画完全结束后,再更新状态渲染蓝色盒子。
示例代码
import { useState, useRef, useEffect } from 'react'; export default function App() { const [isExpanding, setIsExpanding] = useState(false); const [showInnerBox, setShowInnerBox] = useState(false); const yellowBoxRef = useRef(null); useEffect(() => { const box = yellowBoxRef.current; if (isExpanding && box) { const handleTransitionEnd = (e) => { // 仅监听宽度属性的过渡结束事件 if (e.propertyName === 'width') { setShowInnerBox(true); box.removeEventListener('transitionend', handleTransitionEnd); } }; box.addEventListener('transitionend', handleTransitionEnd); } }, [isExpanding]); const handleClick = () => { setIsExpanding(true); setShowInnerBox(false); // 重置内部盒子状态,确保每次点击都能重新触发流程 }; return ( <div className="app"> <button onClick={handleClick}>展开盒子</button> {isExpanding && ( <div ref={yellowBoxRef} className="yellow-box" style={{ width: isExpanding ? '100px' : '0' }} > {showInnerBox && <div className="blue-box"></div>} </div> )} </div> ); }
对应的CSS样式:
.app { margin: 20px; } .yellow-box { height: 100px; background-color: yellow; transition: width 0.5s ease; overflow: hidden; /* 防止内部元素在父盒子未展开时提前显示 */ width: 0; /* 初始宽度为0,挂载后过渡到100px */ } .blue-box { width: 80px; height: 80px; background-color: blue; margin: 10px; }
核心说明
- 黄色盒子通过
isExpanding状态实现条件挂载,避免了始终挂载带来的额外问题 - 利用
transitionend事件精准控制蓝色盒子的渲染时机,确保严格遵循动画完成后再渲染的顺序 - 通过
useRef获取DOM元素绑定事件,保证事件监听仅作用于当前挂载的黄色盒子
内容的提问来源于stack exchange,提问作者Snookums
相关产品推荐
相关产品推荐

