Search code examples
react-nativereact-native-animatable

React Native ref is undefined until page reload


I am using refs to animate a View, but the refs are throwing an undefined error. However, if I comment-out my attempt to access the ref, load the page, un-comment the code, & reload the page, the animation works fine.

My code:

    export const AccountScreen = ({ navigation }) => {
        
          return (
            <SafeAreaView style={{ backgroundColor:'#FFFFFF', flex: 1 }}>
              <Animatable.View style={styles.container} ref={ref => {this.containerRef = ref}}>
              </Animatable.View>
            </SafeAreaView>
          )
      };

   launchOpenAnimation()
   function launchOpenAnimation () {
     this.containerRef.animate(appearContainerAnimation); //If I comment this out, reload, and un-comment, it works
   }

What can I do to fix this? It appears that the ref isn't defined at the time that my launchOpenAnimation() is executed, but that it is defined after, thus resulting in the code working if I comment it out, reload, un-comment, and reload again.


Solution

  • First thing first, your question is messed up between calls component and functional component, cuz there is no this in functional component. I'll convert them to function component using useRef and useEffect

    In the first run this.containerRef have not be assign to ref of Animatable yet.

    Try this

    export const AccountScreen = ({ navigation }) => { 
      const animateRef = useRef()
      useEffect(() =>{
         launchOpenAnimation()
         function launchOpenAnimation () {
           // add ? to make sure animate is called only when this.containerRef exists
         containerRef?.current.animate(appearContainerAnimation);
    }    
      },[])
          
      return (
        <SafeAreaView style={{ backgroundColor:'#FFFFFF', flex: 1 }}>
          <Animatable.View style={styles.container} ref={ref => {
                ref.animate(appearContainerAnimation); // add this if you need to run when initial render run
                animateRef.current = ref
                }}>
          </Animatable.View>
        </SafeAreaView>
      )
    };