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

React中useEffect结合Animated.timing反向动画未正常显示问题

解决React中useEffect结合Animated.timing反向动画跳变的问题

嘿,我一眼就看出问题所在了——你的滑块反向切换时直接跳变,核心原因是动画状态没有被持久化。

你现在在组件里直接声明const transformX = new Animated.Value(0),每次active变化导致Slider组件重新渲染时,都会创建一个全新的Animated.Value实例,之前的动画进度直接丢失了。比如当你从Pickup切回Delivery时,新的transformX初始值就是0,这时候Animated.timing其实是从0到0,看起来就像滑块直接跳回去,而动画回调还是会执行(毕竟动画“完成”了)。

修复方案:用useRef持久化Animated.Value实例

我们需要让transformX在组件整个生命周期内保持同一个实例,这时候useRef就派上用场了,它能帮我们保存不会随渲染重置的变量。修改后的Slider组件代码如下:

const Slider = ({sliderWidth, circleHeight, active, onToggle}) => { 
  // 用useRef保存Animated.Value,确保组件渲染时不会重新创建
  const transformXRef = React.useRef(new Animated.Value(0));
  const transformX = transformXRef.current;

  React.useEffect(() => { 
    console.log('only run when active changed', transformX); 
    const value = active ? sliderWidth - circleHeight : 0; 
    console.log('value', value); 
    Animated.timing(transformX, { 
      toValue: value, 
      duration: 500, 
      useNativeDriver: true 
    }).start(() => console.log('animation done')); 
  }, [active, sliderWidth, circleHeight]); // 这里可以去掉transformX,因为ref的current是稳定的

  return ( 
    <View style={{position: 'absolute',width: sliderWidth+10, backgroundColor: 'white', borderBottomLeftRadius: 8, borderBottomRightRadius: 8, flexDirection: 'column', alignItems: 'center'}}> 
      <View style={{width: sliderWidth, borderRadius: sliderWidth/2, borderWidth: 1, height: circleHeight,justifyContent: 'center', alignItems: 'center', marginTop: 8, marginBottom: 8, backgroundColor: 'white'}}> 
        <Text style={{fontSize: 11}}> {active ? "Pickup" : "Delivery"} </Text> 
        <TouchableOpacity onPress={onToggle} style={{position: 'absolute', left:0, transform: [{translateX: transformX}]}}> 
          <View style={{height: circleHeight-2, width: circleHeight-2, borderRadius: circleHeight/2-1, backgroundColor: 'orange' }} /> 
        </TouchableOpacity> 
      </View> 
    </View> 
  ); 
}; 

关键修改说明:

  1. 用useRef保存动画值:useRef创建的对象在组件挂载后就不会再改变,它的current属性会一直指向同一个Animated.Value实例,这样动画状态就能在组件渲染之间保留下来。
  2. 优化useEffect依赖:因为transformXRef是稳定的ref对象,所以不需要把transformX加入useEffect的依赖数组,避免不必要的触发。

这样修改后,不管你是切换到Pickup还是Delivery,滑块都会从当前位置平滑过渡到目标位置,完全符合你想要的来回平滑切换效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 14:22:33