question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

When try to do an Animation and change a hook state at the same time, the animation doesn't work

See original GitHub issue

When try to do an Animation and change a hook state at the same time, the animation doesn’t work. I’m trying to animate a View using translateY, but when I try to change the value of a state variable, the animation doesn’t work properly, without the state change, everything works.

React Native version:

React Native Environment Info:
    System:
      OS: macOS 10.14.5
      CPU: (6) x64 Intel(R) Core(TM) i5-8500B CPU @ 3.00GHz
      Memory: 37.39 MB / 8.00 GB
      Shell: 5.3 - /bin/zsh
    Binaries:
      Node: 10.15.3 - ~/.nvm/versions/node/v10.15.3/bin/node
      Yarn: 1.16.0 - ~/.nvm/versions/node/v10.15.3/bin/yarn
      npm: 6.4.1 - ~/.nvm/versions/node/v10.15.3/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    SDKs:
      iOS SDK:
        Platforms: iOS 12.2, macOS 10.14, tvOS 12.2, watchOS 5.2
      Android SDK:
        API Levels: 23, 28
        Build Tools: 28.0.3, 29.0.0
        System Images: android-24 | Google Play Intel x86 Atom, android-28 | Google Play Intel x86 Atom, android-Q | Google APIs Intel x86 Atom
    IDEs:
      Android Studio: 3.4 AI-183.5429.30.34.5452501
      Xcode: 10.2.1/10E1001 - /usr/bin/xcodebuild
    npmPackages:
      react: 16.8.3 => 16.8.3 
      react-native: 0.59.8 => 0.59.8 
    npmGlobalPackages:
      react-native-cli: 2.0.1

Steps To Reproduce

  1. Create an Animated.View and set a translateY animated variable;
  2. Call a method to start animation and in start callback call another function to change the value of a variable in state using useState hook.

Describe what you expected to happen: Should animations work properly with useState hook.

Snack, code example, or link to a repository:

  • Just create this component anywhere to test.
import React, { useState } from 'react'
import {
  View, Button, Animated, Easing,
} from 'react-native'

export default function Component() {
  const [opened, setOpened] = useState(false)

  const animatedValue = new Animated.Value(0)

  const translateX = animatedValue.interpolate({
    inputRange: [0, 1],
    outputRange: [0, 80],
  })

  function showSearch() {
    Animated.timing(animatedValue, {
      toValue: 1,
      duration: 150,
      easing: Easing.linear,
    }).start()
  }

  function hideSearch() {
    Animated.timing(animatedValue, {
      toValue: 0,
      duration: 100,
      easing: Easing.linear,
    }).start()
  }

  function showSearchWithUseState() {
    Animated.timing(animatedValue, {
      toValue: 1,
      duration: 150,
      easing: Easing.linear,
    }).start(() => {
      setOpened(true)
    })
  }

  function hideSearchWithUseState() {
    Animated.timing(animatedValue, {
      toValue: 0,
      duration: 100,
      easing: Easing.linear,
    }).start(() => {
      setOpened(false)
    })
  }

  return (
    <View style={{ height: 400 }}>
      <Button title="Show without useState" onPress={showSearch} />
      <Button title="Hide without useState" onPress={hideSearch} />
      {!opened ? (
        <Button title="Show with useState" onPress={showSearchWithUseState} />
      ) : (
        <Button title="Hide with useState" onPress={hideSearchWithUseState} />
      )}
      <Animated.View
        style={{
          height: 80,
          width: 80,
          backgroundColor: '#000',
          transform: [{ translateX }],
        }}
      />
    </View>
  )
}

— EDIT —

I’m testing with a Class based component, and everything is working properly.

import React from 'react'
import {
  View, Button, Animated, Easing,
} from 'react-native'

export default class Component extends React.Component {
  constructor(props) {
    super(props)
    this.state = { opened: false, animatedValue: new Animated.Value(0) }
    this.showSearch = this.showSearch.bind(this)
    this.hideSearch = this.hideSearch.bind(this)
    this.showSearchWithUseState = this.showSearchWithUseState.bind(this)
    this.hideSearchWithUseState = this.hideSearchWithUseState.bind(this)
  }

  showSearch() {
    const { animatedValue } = this.state
    Animated.timing(animatedValue, {
      toValue: 1,
      duration: 150,
      easing: Easing.linear,
    }).start()
  }

  hideSearch() {
    const { animatedValue } = this.state
    Animated.timing(animatedValue, {
      toValue: 0,
      duration: 150,
      easing: Easing.linear,
    }).start()
  }

  showSearchWithUseState() {
    const { animatedValue } = this.state
    Animated.timing(animatedValue, {
      toValue: 1,
      duration: 150,
      easing: Easing.linear,
    }).start(() => {
      this.setState(() => ({ opened: true }))
    })
  }

  hideSearchWithUseState() {
    const { animatedValue } = this.state
    Animated.timing(animatedValue, {
      toValue: 0,
      duration: 150,
      easing: Easing.linear,
    }).start(() => {
      this.setState(() => ({ opened: false }))
    })
  }

  render() {
    const { opened, animatedValue } = this.state
    return (
      <View style={{ height: 400 }}>
        <Button title="Show without useState" onPress={this.showSearch} />
        <Button title="Hide without useState" onPress={this.hideSearch} />
        {!opened ? (
          <Button title="Show with useState" onPress={this.showSearchWithUseState} />
        ) : (
          <Button title="Hide with useState" onPress={this.hideSearchWithUseState} />
        )}
        <Animated.View
          style={{
            height: 80,
            width: 80,
            backgroundColor: '#000',
            transform: [
              {
                translateX: animatedValue.interpolate({
                  inputRange: [0, 1],
                  outputRange: [0, 80],
                }),
              },
            ],
          }}
        />
      </View>
    )
  }
}

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:1
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

20reactions
dudusoterocommented, Jun 5, 2019

Done, more easy than everything lol. Thank you @thymikee !!

The solution for this is only add another variable to be a reference for ‘animatedValue’.

import React, { useState, useRef } from 'react'
import {
  View, Button, Animated, Easing,
} from 'react-native'

export default function Component() {
  const [opened, setOpened] = useState(false)

  const animatedValue = new Animated.Value(0)
  const animatedValueRef = useRef(animatedValue)

  const translateX = animatedValueRef.current.interpolate({
    inputRange: [0, 1],
    outputRange: [0, 80],
  })

  function showSearch() {
    Animated.timing(animatedValue, {
      toValue: 1,
      duration: 150,
      easing: Easing.linear,
    }).start()
  }

  function hideSearch() {
    Animated.timing(animatedValue, {
      toValue: 0,
      duration: 100,
      easing: Easing.linear,
    }).start()
  }

  function showSearchWithUseState() {
    Animated.timing(animatedValueRef.current, {
      toValue: 1,
      duration: 150,
      easing: Easing.linear,
    }).start(() => {
      setOpened(true)
    })
  }

  function hideSearchWithUseState() {
    Animated.timing(animatedValueRef.current, {
      toValue: 0,
      duration: 100,
      easing: Easing.linear,
    }).start(() => {
      setOpened(false)
    })
  }

  return (
    <View style={{ height: 400 }}>
      <Button title="Show without useState" onPress={showSearch} />
      <Button title="Hide without useState" onPress={hideSearch} />
      {!opened ? (
        <Button title="Show with useState" onPress={showSearchWithUseState} />
      ) : (
        <Button title="Hide with useState" onPress={hideSearchWithUseState} />
      )}
      <Animated.View
        style={{
          height: 80,
          width: 80,
          backgroundColor: '#000',
          transform: [{ translateX }],
        }}
      />
    </View>
  )
}
5reactions
thymikeecommented, Jun 5, 2019

I knew you can make it! Awesome you shared the solution as well, thank you 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

Usestate is not updating - Stack Overflow
I am trying to update the value of a state at the end of an animation, but when I am trying to do...
Read more >
Animation Classes & useEffect Hooks - Is There a Better Way?
When applying a hidden class at the same time as an animation class, the animation didn't happen - just the disappearing :). Solution....
Read more >
Animation event not triggering - Unity Forum
Currently in my game a lot of events are triggered from within an animation and occasionally they seem to be skipped over.
Read more >
'While' Animations and Initial - The Framer book
'While' Animations and Initial. With the whileHover , whileTap , and whileDrag gesture animations, you can quickly make layers interactive.
Read more >
Hooks at a Glance - React
Hooks are functions that let you “hook into” React state and lifecycle features from function components. Hooks don't work inside classes — they...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found