React+Typescript 点击新增数据后自动滚动到容器底部功能异常求助
问题原因
- 基础语法错误:
- 状态声明错将
useState写为useEffect,状态更新逻辑本身存在异常 - 父组件传递ref时拼写错误,声明的变量是
myRef,传递时写为myref,导致ref绑定失效
- 状态声明错将
- 核心逻辑错误:React的状态更新是异步批量执行的,调用
setOldData后立刻触发滚动时,新数据对应的子div还没有渲染到DOM中,此时滚动的锚点位置仍是旧数据渲染完成后的位置,所以无法滚动到新的底部。
修复方案
- 修正基础语法错误
- 把滚动逻辑放到
useEffect中,监听数据数组的变化,等数据更新、DOM重新渲染完成后再触发滚动 - 给
scrollIntoView添加配置参数,确保滚动对齐到元素底部
修复后代码
ParentComponent.tsx
import { useRef, useEffect, useState } from "react" import { ChildComponent } from './ChildComponent' // 抽离公共类型 interface DummyModel { id: number content: string } export const SearchResult = () => { const myRef = useRef<null | HTMLDivElement>(null) // 修正状态声明,使用useState const [oldData, setOldData] = useState<DummyModel[]>([]) const executeScroll = () => { // 滚动配置,block: end表示对齐元素底部 myRef.current?.scrollIntoView({ behavior: "smooth", block: "end" }) } const addMoreData = () => { let data = { id: Date.now(), // 替换固定id,避免重复 content: 'dummy content' } setOldData(prev => [...prev, data]) } // 监听数据变化,DOM更新完成后再触发滚动 useEffect(() => { executeScroll() }, [oldData]) return ( <div> <button onClick={addMoreData}>Click Me</button> <ChildComponent ref={myRef} {/* 修正ref拼写 */} someData={oldData} /> </div> ) }
ChildComponent.tsx
import React from 'react' interface DummyModel { id: number content: string } export interface ChildComponentProps { someData: DummyModel[] } export const ChildComponent = React.forwardRef<HTMLDivElement, ChildComponentProps>(({ someData }, ref) => { return ( <div> <div className="parent_div"> {someData.map((v) => { return ( // 替换索引为唯一key,避免列表渲染异常 <div key={v.id} className="child_div"> {v.content} </div> ) }) } </div> <div ref={ref}></div> </div> ) })
内容的提问来源于stack exchange,提问作者Yogesh k
相关产品推荐
相关产品推荐

