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
相关产品推荐
相关产品推荐

