React渲染后滚动实现:手风琴组件展开后滚动至元素顶部
问题解决:手风琴展开后精准滚动到顶部
你的问题核心在于React状态更新的异步特性:点击切换按钮时,调用setIsToggleOpen(!isToggleOpen)后,isToggleOpen不会立即同步更新,children也不会瞬间渲染到DOM中。此时执行滚动操作,DOM布局还未因展开内容发生变化,滚动计算基于旧的页面高度,自然无法精准定位到顶部。
修复方案
通过useEffect监听isToggleOpen的状态变化,当状态从false切换为true(即手风琴完成展开)时再执行滚动——这时候children已经渲染完毕,DOM布局更新完成,滚动位置会精准对齐屏幕顶部。
修改后的代码:
const WeirdAlAccordion: React.FC<MyProps> = ({ children, }: MyProps) => { const scrollingRef = useRef<HTMLDivElement>(null); const [isToggleOpen, setIsToggleOpen] = useState(false); // 监听状态变化,仅在展开时执行滚动 useEffect(() => { if (isToggleOpen && scrollingRef.current) { scrollingRef.current.scrollIntoView({ block: 'start', inline: 'nearest', behavior: 'smooth' // 可选,开启平滑滚动效果 }); } }, [isToggleOpen]); // 仅当isToggleOpen状态改变时触发 return ( <> <div id="my-id" ref={scrollingRef}> <IonItem> <HandednessToggle checked={isToggleOpen} onClick={() => setIsToggleOpen(!isToggleOpen)} label="My Label" disabled={isAccordionKeyDisabled} /> </IonItem> {isToggleOpen && children} </div> </> ); };
关键改动说明
- 移除了
onClick回调中直接调用滚动的逻辑,避免在DOM未更新时执行无效计算。 - 用
useEffect绑定状态变化,确保滚动操作在DOM布局更新后执行。 - 给
scrollingRef添加TypeScript类型标注,提升代码安全性。 - 可选的
behavior: 'smooth'参数可实现平滑滚动,不需要可直接移除。
内容的提问来源于stack exchange,提问作者Patrick Kenny
相关产品推荐
相关产品推荐

