如何用React Spring实现高度自适应动画并解决路由跳转后失效问题
修复方案
核心问题排查
你的代码存在3个直接导致页面返回后动画失效的问题:
- 事件监听写法错误:
useEffect中直接执行了setContentHeight(height),相当于给resize事件绑定了undefined作为回调,且清理函数没有返回包裹移除逻辑的函数,不仅监听不生效还会产生内存泄漏。 - 高度类型不匹配:
contentHeight初始值为字符串"100px",后续拼接${contentHeight}px会生成"100pxpx"的非法CSS值,导致高度计算异常。 - 重挂载状态不同步:页面跳转后组件卸载再挂载时,useMeasure返回的初始高度可能为0,useSpring会缓存上一次的高度状态,无法和最新渲染的内容高度同步。
修复后代码
const defaultHeight = 100; // 改为数字类型避免拼接出非法高度值 const [contentHeight, setContentHeight] = useState(defaultHeight); const [ref, { height }] = useMeasure(); const expand = useSpring({ config: { ...config.default, duration: 250 }, height: `${contentHeight}px`, }); useEffect(() => { // 过滤高度为0的无效测量值 if (height > 0) { setContentHeight(height); } // 定义独立的resize回调函数 const handleResize = () => { if (height > 0) setContentHeight(height); }; window.addEventListener("resize", handleResize); // 清理函数返回包裹移除逻辑的函数 return () => { window.removeEventListener("resize", handleResize); }; }, [height]); // JSX原有逻辑保持不变 return ( <div className="team-management"> <div className="team-management-tabs-header"> <div className="team-management-tab-items"> {tabs.map((tab, index) => ( <div id={editable === true ? "" : `${tab}`} className={ activeTab === index ? "team-management-tab-item selected" : "team-management-tab-item" } key={tab} role="button" tabIndex={tab} onKeyPress={() => { return; }} onClick={() => { if (editable === true) { setActiveTab(index); } else if (index !== 5 && index !== 6) { setActiveTab(index); } }} > {teamData.type === "organization" ? ( <span className="tab-item-text">{tab}</span> ) : ( <> {tab !== "Sub-Team" && ( <span className="tab-item-text">{tab}</span> )} </> )} <span className="tab-item-indicator" /> </div> ))} </div> </div> <animated.div style={expand}> <div className="team-management-tab-panes" ref={ref}> {tabs[activeTab] === "Mission" && ( <Mission editable={editable} teamId={teamId} teamData={teamData} fetchTeamData={fetchTeamData} notify={notify} /> )} {tabs[activeTab] === "Managers" && <Managers members={members} />} {tabs[activeTab] === "Members" && ( <Members members={members} teamId={teamId} tab={tabs[activeTab]} userPublicId={userPublicId} fetchTeamData={fetchTeamData} notify={notify} /> )} {tabs[activeTab] === "Invitees" && ( <Invitees teamData={teamData} teamId={teamId} privateTeamId={teamData.id} fetchTeamData={fetchTeamData} tab={tabs[activeTab]} /> )} {tabs[activeTab] === "Sub-Team" && ( <SubTeam teamId={teamId} teamData={teamData} members={members} fetchTeamData={fetchTeamData} /> )} </div> </animated.div> </div> );
内容的提问来源于stack exchange,提问作者Nhan Nguyen
相关产品推荐
相关产品推荐

