React中实现点击map生成的tab项滚动到对应同名映射标题的问题
问题原因
所有标题的id属性都写死为固定值heading,而同一个HTML页面内元素id必须全局唯一,浏览器匹配锚点时只会返回第一个找到的对应id元素,因此所有链接都会跳转到第一个标题。无需强制使用ref实现,原生锚点只要保证id和跳转链接的锚点值一一对应即可正常工作。
方案1:原生锚点实现(最简方案)
直接将href和标题的id绑定每个group的唯一标识即可,示例修改代码如下:
<FormGroupWrapper> {props.groups.map((group) => { // 处理特殊字符,避免id含空格、特殊符号导致匹配失败 const anchorId = encodeURIComponent(group.displayNames) return ( <DisplayNameTab key={group.displayNames}> <a href={`#${anchorId}`}>{group.displayNames}</a> </DisplayNameTab> ) )} </FormGroupWrapper> <FormGroupWrapper> {props.groups.map((group) => { const anchorId = encodeURIComponent(group.displayNames) return ( <DisplayNameTab key={group.displayNames}> <h1 id={anchorId}>{group.displayNames}</h1> <p>{group.description}</p> </DisplayNameTab> ) )} </FormGroupWrapper>
如果需要平滑滚动效果,只需在全局CSS中添加:
html { scroll-behavior: smooth; }
注意:如果
group有独立的唯一id字段,优先用id作为锚点值,比displayName稳定性更高。
方案2:ref+scrollIntoView实现(适合自定义滚动行为场景)
如果需要控制滚动偏移、动画触发时机等自定义逻辑,可以用ref实现:
import { useRef } from 'react' // 组件内定义ref存储所有标题的DOM引用 const titleRefs = useRef({}) // 渲染部分修改 <FormGroupWrapper> {props.groups.map((group) => { return ( <DisplayNameTab key={group.displayNames}> <a href="#" onClick={(e) => { e.preventDefault() // 自定义滚动参数 titleRefs.current[group.displayNames]?.scrollIntoView({ behavior: 'smooth', block: 'start', // 如有固定头部需要偏移,可以额外添加偏移处理逻辑 }) }} > {group.displayNames} </a> </DisplayNameTab> ) )} </FormGroupWrapper> <FormGroupWrapper> {props.groups.map((group) => { return ( <DisplayNameTab key={group.displayNames}> <h1 ref={el => titleRefs.current[group.displayNames] = el}>{group.displayNames}</h1> <p>{group.description}</p> </DisplayNameTab> ) )} </FormGroupWrapper>
内容的提问来源于stack exchange,提问作者walker1
相关产品推荐
相关产品推荐

