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

React Native Reanimated组件间依赖动画的组织模式咨询

解决React Native Reanimated组件间动画依赖的正确模式

核心思路

摒弃硬编码延迟的方式,通过子组件动画完成回调通知+父组件状态追踪的组合,让父组件精准感知所有子组件的动画结束时机,再触发自身动画,完全贴合实际动画执行状态,不受设备性能或动画波动影响。


具体实现方案

1. 改造InnerComponent:添加动画完成回调

让子组件支持接收外部传入的onAnimationComplete回调,利用withTiming的内置callback参数,在自身动画结束时主动通知父组件。

import React from 'react';
import { View } from 'react-native';
import { useSharedValue, withTiming, useAnimatedStyle } from 'react-native-reanimated';

type InnerComponentProps = {
  onAnimationComplete?: () => void;
  // 其他自定义props
};

const InnerComponent = ({ onAnimationComplete }: InnerComponentProps) => {
  const translateX = useSharedValue(0);

  React.useEffect(() => {
    // 启动位移动画,结束时触发回调
    translateX.value = withTiming(100, { duration: 500 }, () => {
      onAnimationComplete?.();
    });
  }, []);

  const animatedStyle = useAnimatedStyle(() => ({
    transform: [{ translateX: translateX.value }],
  }));

  return <View style={[{ width: 50, height: 50, backgroundColor: 'blue' }, animatedStyle]} />;
};

export default InnerComponent;

2. 父组件:追踪所有子组件的完成状态

在父组件中维护一个计数器,每收到一个子组件的完成通知就递增计数,当计数等于子组件总数时,立即触发自身动画。

import React, { useState, useCallback } from 'react';
import { View } from 'react-native';
import { useSharedValue, withTiming, useAnimatedStyle } from 'react-native-reanimated';
import InnerComponent from './InnerComponent';

const ParentComponent = () => {
  const totalChildren = 6;
  const [completedAnimations, setCompletedAnimations] = useState(0);
  const parentTranslateY = useSharedValue(0);

  // 统一处理子组件的完成通知
  const handleChildDone = useCallback(() => {
    setCompletedAnimations(prev => {
      const newCount = prev + 1;
      // 所有子组件动画完成,触发父组件动画
      if (newCount === totalChildren) {
        parentTranslateY.value = withTiming(-50, { duration: 300 });
      }
      return newCount;
    });
  }, [totalChildren]);

  const parentAnimatedStyle = useAnimatedStyle(() => ({
    transform: [{ translateY: parentTranslateY.value }],
  }));

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', gap: 10 }}>
      <View style={parentAnimatedStyle}>
        {Array.from({ length: totalChildren }).map((_, idx) => (
          <InnerComponent key={idx} onAnimationComplete={handleChildDone} />
        ))}
      </View>
    </View>
  );
};

export default ParentComponent;

3. 进阶优化:用Reanimated共享值避免重渲染

如果担心React状态更新导致父组件频繁重渲染,可以改用Reanimated的sharedValue追踪完成计数,结合addListener监听变化:

// 父组件内替换状态相关代码
import { addListener } from 'react-native-reanimated';

const completedCount = useSharedValue(0);
const parentTranslateY = useSharedValue(0);
const totalChildren = 6;

const handleChildDone = useCallback(() => {
  completedCount.value += 1;
}, []);

React.useEffect(() => {
  // 监听共享值变化
  const unsubscribe = addListener(completedCount, () => {
    if (completedCount.value === totalChildren) {
      parentTranslateY.value = withTiming(-50, { duration: 300 });
    }
  });
  return unsubscribe;
}, [totalChildren]);

方案优势

  • 精准可靠:完全基于实际动画完成事件触发,不会出现提前或延迟执行的问题
  • 可扩展:子组件数量变化时,只需修改totalChildren参数,无需调整任何动画逻辑
  • 低耦合:子组件仅负责通知状态,父组件负责判断逻辑,组件职责清晰

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 22:09:22