Reanimated中如何让动画在组件卸载前完成?

令狐子轩 阅读 23

我用Reanimated做了一个下拉菜单的关闭动画,但一点击关闭就立刻unmount组件,动画根本没机会执行完。试过加runOnJS延迟卸载也不行,有啥靠谱的办法吗?

这是我的简化代码:

const opacity = useSharedValue(1);

const handleClose = () => {
  opacity.value = withTiming(0, { duration: 300 }, () => {
    // 这里想等动画结束再卸载组件,但父组件收不到信号
  });
};
我来解答 赞 8 收藏
二维码
手机扫码查看
1 条解答
司马俊蓓
这个问题很简单,动画完成后通过回调通知父组件卸载就行。

你代码里 withTiming 第三个参数就是动画结束回调,在那里通知父组件:

// 子组件
const AnimatedView = Animated.createAnimatedComponent(View);

const Menu = ({ onClose }) => {
const opacity = useSharedValue(1);

const handleClose = () => {
opacity.value = withTiming(0, { duration: 300 }, (finished) => {
if (finished) {
onClose(); // 动画完成后再通知父组件卸载
}
});
};

const animatedStyle = useAnimatedStyle(() => ({
opacity: opacity.value,
}));

return (
<AnimatedView style={animatedStyle}>
<TouchableOpacity onPress={handleClose} />
</AnimatedView>
);
};

// 父组件
const [menuVisible, setMenuVisible] = useState(true);

return (
<>
{menuVisible && (
<Menu onClose={() => setMenuVisible(false)} />
)}
</>
);


关键点就是条件渲染 {menuVisible && },点击关闭时先播动画,动画完再 setMenuVisible(false) 触发真正卸载。

如果你用的是 Modal 或者 Portal,也可以把 visible 属性传进去让父组件控制卸载时机。
点赞
2026-03-18 11:01