You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Spring translate动画不生效、列表项点击延迟问题求解

问题根因

  1. 状态更新异步导致参数错误:React中setState为异步批量更新逻辑,你在点击回调中更新currentIndex、previousIndex后立即调用fn()获取动画参数,此时读取的两个索引仍是更新前的旧值,导致首次点击的动画配置错误,需要第二次点击才能拿到上一次更新的正确索引。
  2. 高亮条渲染逻辑错误:你将animated.div放在选项循环内部,且添加了currentIndex === index的条件判断,每次切换选中项时,旧位置的高亮条会直接被卸载,新位置的高亮条重新挂载,不会触发过渡动画,只会直接显隐。
  3. react-spring用法错误:无需将useSpring的返回值包裹在useState中,useSpring本身会返回响应式的动画样式对象以及更新动画的API方法,自行用useState包裹会打断动画状态的响应式更新链路。

修复后代码

import { useSpring, animated } from '@react-spring/web'
import { useState } from 'react'
import TextWithIcon from './TextWithIcon'

// 示例options结构,可根据实际业务调整
const options = [
  { name: 'Option 1', filledIcon: <>填充实例1</>, outlineIcon: <>线框实例1</> },
  { name: 'Option 2', filledIcon: <>填充实例2</>, outlineIcon: <>线框实例2</> },
  { name: 'Option 3', filledIcon: <>填充实例3</>, outlineIcon: <>线框实例3</> },
]

const Menu = () => {
  const [currentIndex, setCurrentIndex] = useState<number>(0)
  // 正确使用useSpring,返回动画样式和更新API
  const [spring, api] = useSpring(() => ({
    transform: `translateY(0px)`,
  }))

  const onClick = (name: string, index: number) => {
    setCurrentIndex(index)
    // 直接用点击传入的index计算目标位置,不依赖异步更新的state
    api.start({
      transform: `translateY(${index * 52}px)`,
    })
  }

  return (
    {/* 外层容器添加相对定位,作为高亮条的定位父级 */}
    <div style={{ position: 'relative' }}>
      {/* 高亮条移出循环,仅渲染一次,靠translateY实现滑动 */}
      <animated.div 
        style={{
          ...spring,
          background: 'orange',
          height: 52,
          width: '100%',
          position: 'absolute',
          left: 0,
          zIndex: 1
        }}
      />
      {options.map((option, index) => (
        <div 
          key={option.name} 
          onClick={() => onClick(option.name, index)}
          {/* 选项层级高于高亮条,避免文字被遮挡 */}
          style={{ height: 52, position: 'relative', zIndex: 2 }}
        >
          <TextWithIcon 
            icon={currentIndex === index ? option.filledIcon : option.outlineIcon} 
            text={option.name} 
          />
        </div>
      ))}
    </div>
  )
}

export default Menu

TextWithIcon组件本身逻辑无问题,无需修改。


内容的提问来源于stack exchange,提问作者user2387766

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 20:45:04