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

React Native中react-native-animatable返回页面后动画不重放问题

Fixing react-native-animatable Trigger on Tab Navigation Return

Hey there! I see you're running into an issue where your animatable views only play their animations on the first load, but not when navigating back to the Home tab. You're spot-on about the root cause—since the component doesn't remount when you return, the animation prop only triggers once on initial mount. Let's walk through a couple of solid solutions to fix this.

The cleanest approach is to listen for when the Home screen comes back into focus, then manually trigger each animation using the animatable component's animate() method. Here's how to adjust your class component code:

Step 1: Create Refs for Animatable Views

First, add refs to each of your animatable <View> components so we can call their animation methods later:

import React, { Component } from 'react';
// ... other imports

class Home extends React.Component {
  constructor(props) {
    super(props);
    // Create refs for each animated view
    this.bounceLeft1Ref = React.createRef();
    this.bounceRightRef = React.createRef();
    this.bounceLeft2Ref = React.createRef();
  }

Step 2: Add Navigation Focus Listener

Next, set up a listener for the focus event (from React Navigation) in componentDidMount. When the screen focuses, we'll call the animate() method on each ref:

componentDidMount() {
  const { navigation } = this.props;
  // Listen for when the screen comes into focus
  this.focusListener = navigation.addListener('focus', () => {
    // Trigger each animation
    this.bounceLeft1Ref.current?.animate('bounceInLeft');
    this.bounceRightRef.current?.animate('bounceInRight');
    this.bounceLeft2Ref.current?.animate('bounceInLeft');
  });
}

// Clean up the listener when the component unmounts
componentWillUnmount() {
  this.focusListener();
}

Step 3: Attach Refs to Your Views

Update your render method to assign the refs to each animatable <View>:

render() {
  return (
    <View style={styles.container}>
      <View 
        ref={this.bounceLeft1Ref} 
        animation='bounceInLeft' 
        style={styles.container1}
      >
        <View style={styles.card1}>
          <ImageBackground source={require('../images/pictures/runop.jpg')} style={{width:'100%', height:200, }}>
            <Text style={{fontSize:30, alignSelf:'center', color:'white', fontFamily:Fonts.Nunito}} > Sport Schema's</Text>
          </ImageBackground>
        </View>
      </View>
      <View 
        ref={this.bounceRightRef} 
        animation='bounceInRight' 
        style={styles.container2}
      >
        <View style={styles.card2}>
          <Image source={require('../images/pictures/foodop.jpg')} style={{width:'100%', height:200}}/>
        </View>
      </View>
      <View 
        ref={this.bounceLeft2Ref} 
        animation='bounceInLeft' 
        style={styles.container3}
      >
        <View style={styles.card3}>
          <Image source={require('../images/pictures/blogop.jpg')} style={{width:'100%', height:200}}/>
        </View>
      </View>
    </View>
  );
}

This method is efficient because it doesn't force a full component remount—we just trigger the animations directly when needed.

Solution 2: Force Component Remount with a Key

If you prefer a more brute-force approach (though less efficient), you can force the Home component to remount by updating a key prop whenever the screen focuses. This will re-run all initial mount logic, including the animations:

class Home extends React.Component {
  state = {
    componentKey: Date.now()
  };

  componentDidMount() {
    this.focusListener = this.props.navigation.addListener('focus', () => {
      // Update the key to trigger a remount
      this.setState({ componentKey: Date.now() });
    });
  }

  componentWillUnmount() {
    this.focusListener();
  }

  render() {
    return (
      <View key={this.state.componentKey} style={styles.container}>
        {/* Your existing animatable views here */}
      </View>
    );
  }
}

Note: This will re-render your entire Home component and all its children, which might cause unnecessary performance overhead if your component is complex. Stick with Solution 1 unless you have a specific reason to use this.

Bonus: Function Component Version

If you ever decide to convert your class component to a function component, you can use useFocusEffect from React Navigation along with useRef:

import React, { useRef } from 'react';
import { useFocusEffect } from '@react-navigation/native';
// ... other imports

const Home = ({ navigation }) => {
  const bounceLeft1Ref = useRef(null);
  const bounceRightRef = useRef(null);
  const bounceLeft2Ref = useRef(null);

  useFocusEffect(
    React.useCallback(() => {
      bounceLeft1Ref.current?.animate('bounceInLeft');
      bounceRightRef.current?.animate('bounceInRight');
      bounceLeft2Ref.current?.animate('bounceInLeft');
    }, [])
  );

  return (
    <View style={styles.container}>
      <View ref={bounceLeft1Ref} animation='bounceInLeft' style={styles.container1}>
        {/* Card content */}
      </View>
      {/* Repeat for other views */}
    </View>
  );
};

Give these methods a try—your animations should now fire every time you navigate back to the Home screen!

内容的提问来源于stack exchange,提问作者Re-Angelo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:22:44