React Native Reanimated 2:如何避免启动触发动画及实现状态切换反向动画
解决React Native网络状态提示组件的启动显示与动画优化问题
修改后的完整代码
import React, { useState, useEffect, useRef } from 'react'; import { Animated, Node } from 'react-native'; import { useNetInfo } from '@react-native-community/netinfo'; // 请替换为你的自定义组件导入路径 import { HealthStatusContainer, Dot, StatusLabel } from './your-components'; const HealthCheckStatus = (): Node => { // 初始状态设为null,区分未初始化状态和网络可用状态 const [status, setStatus] = useState<boolean | null>(null); const netInfo = useNetInfo(); // 初始值设为-100,让组件默认处于屏幕外(需匹配组件实际高度) const translateY = useRef(new Animated.Value(-100)).current; useEffect(() => { if (netInfo.isInternetReachable !== null) { setStatus(netInfo.isInternetReachable); } }, [netInfo.isInternetReachable]); // 监听网络状态变化,触发对应动画 useEffect(() => { // 初始未初始化状态不触发动画 if (status === null) return; if (!status) { // 网络断开:从屏幕外弹性移入目标位置 Animated.spring(translateY, { toValue: 0, stiffness: 65, useNativeDriver: true, }).start(); } else { // 网络恢复:延迟5秒后平滑移出到屏幕外 Animated.timing(translateY, { toValue: -100, delay: 5000, useNativeDriver: true, }).start(); } }, [status, translateY]); const getStatusLabel = () => { switch (status) { case false: return '连接失败'; case true: return '已连接'; default: return '已连接'; } }; const animatedStyles = useAnimatedStyle(() => ({ transform: [{ translateY }], })); return ( <Animated.View style={animatedStyles}> <HealthStatusContainer> <Dot status={status ?? true} /> <StatusLabel>{getStatusLabel()}</StatusLabel> </HealthStatusContainer> </Animated.View> ); }; export default HealthCheckStatus;
关键改动说明
- 启动隐藏处理:
- 将
status初始值设为null,避免启动时误判网络状态触发动画 translateY初始值设为-100,让组件默认处于屏幕外,启动时完全不可见
- 将
- 单动画值管理:
- 用单个
Animated.Value控制位移,替代原来的两个独立动画样式,状态切换时仅需修改目标值即可实现正向/反向动画
- 用单个
- 精准动画触发:
- 新增
useEffect监听status变化,仅在网络状态从可用变不可用、或不可用变可用时触发对应动画,避免无意义的重复执行
- 新增
- 保留原有动画效果:
- 断网时沿用原有的弹性移入动画,联网时保留5秒延迟后移出的逻辑,确保和需求一致
内容的提问来源于stack exchange,提问作者Raphaël Chemouni
相关产品推荐
相关产品推荐

