When I update a style value using withSpring inside of useAnimatedStyle in 2.0.0-rc.0, it doesn't animate.
Video here.
Notice that when I change the style from withSpring to withTiming, it works fine.
EXPO_BETA=1 expo init bugcd bug && yarn add [email protected]Clicking the button should cause the box to animate to its next state.
If you use withSpring inside of useAnimatedStyle, it won't animate to the next state. Instead, it changes the value without an animation.
import React from 'react'
import { View, Button, StyleSheet } from 'react-native'
import Animated, { useAnimatedStyle, useSharedValue, withSpring, withTiming } from 'react-native-reanimated'
export default function AnimatedStyleUpdateExample() {
const size = useSharedValue(200)
const style = useAnimatedStyle(() => ({
width: withTiming(size.value), // this will animate
height: withSpring(size.value) // this will not
}))
return (
<View style={styles.container}>
<Animated.View style={[styles.box, style]} />
<Button
title="toggle"
onPress={() => {
const randomSize = size.value * (1 + Math.random())
if (size.value > 200) {
size.value = 150
} else {
size.value = randomSize
}
}}
/>
</View>
)
}
const styles = StyleSheet.create({
box: { justifyContent: 'center', backgroundColor: 'blue' },
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'column'
}
})
If you prefer, you can close this repo, run yarn start, and open Bug.tsx.
(Expo Snack doesn't support Reanimated v2 โ sorry!)
If I use withSpring when I mutate the value, it works fine.
// โ
this works
const size = useSharedValue(200)
const style = useAnimatedStyle(() => ({
width: size.value,
height: size.value
}))
const onPress = () => {
const randomSize = size.value * (1 + Math.random())
if (size.value > 200) {
size.value = withSpring(150)
} else {
size.value = withSpring(randomSize)
}
}
However, if I mutate the shared value directly, and then apply withSpring inside of useAnimatedStyle, it does not work.
// ๐จ this does not work
const size = useSharedValue(200)
const style = useAnimatedStyle(() => ({
width: withSpring(size.value),
height: withSpring(size.value)
}))
const onPress = () => {
const randomSize = size.value * (1 + Math.random())
if (size.value > 200) {
size.value = 150
} else {
size.value = randomSize
}
}
package.json
{
"version": "39.0.0",
"dependencies": {
"expo": "^40.0.0-beta.5",
"expo-status-bar": "~1.0.3",
"react": "16.13.1",
"react-dom": "16.13.1",
"react-native": "https://github.com/expo/react-native/archive/sdk-40.0.0.tar.gz",
"react-native-gesture-handler": "~1.8.0",
"react-native-reanimated": "2.0.0-rc.0",
"react-native-web": "~0.13.12",
},
"devDependencies": {
"@babel/core": "~7.9.0",
"@types/lodash.set": "^4.3.6",
"babel-preset-expo": "8.3.0",
},
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo web",
"eject": "expo eject"
},
"private": true
}
app.json
{
"expo": {
"experiments": {
"turboModules": true
}
}
}
16.13.1https://github.com/expo/react-native/archive/sdk-40.0.0.tar.gz2.0.0-rc.0v14.2.0Thank you!
Hello!
Congratulations! Your issue passed the validator! Thank you!
Had same issue. Pass spring config with mass, damping, stiffness and velocity. Be careful about velocity - correct value for me was โ2โ, not really sure why.
@andreyco are these values required? The TS types have the second argument as optional. Same goes for the docs.
Setting a velocity: 2 did indeed fix this for me as well. The docs don't even show velocity as an option, so they are likely out of date(?) I wonder if this should have a default so that it doesn't require a second argument.
This fixed the issue https://github.com/software-mansion/react-native-reanimated/pull/1496
It is going to be included in the next release.
You can get a package of the current master built daily here.
@karol-bisztyga thanks!
Is there a way to know if an update is compatible with expo (i.e. if it has native code changes?) I appreciate your help!
I wrote a small script for this a while ago:
# check if version corresponds to changes in native files
if git diff --name-only ${latestVersion} HEAD | egrep '(android/.*)|(ios/.*)' -q ; then egrep '\\.0$' -q <<< ${version} ; else true ; fi ;
The latest version is the update's tag, the version is the previous tag.
Hope it helps.
@jakub-gonet thanks for that! Sorry for the second question here, but I'm not really familiar with bash. Would I just run this in the terminal inside of the reanimated repo? When I do, nothing happens. Thanks again!
Yeah, seems like I forgot to edit JS interpolation ๐
Below is easier to understand version:
PREV='1.9.0'; CURR='1.13.0'; git diff --name-only "$PREV" "$CURR" | egrep '(android/.*)|(ios/.*)'
You just plug the previous and current version of Reanimated into those variables and everything should work (CURR='HEAD' uses the latest commit from the repo). You just need to run it in the Reanimated repository (git cloned)
@jakub-gonet I'm trying this out, but I see an empty output after pressing enter. Does this mean the changes are all JS?
PREV='2.0.0-rc.0'; CURR='2.0.0-rc.1'; git diff --name-only "$PREV" "$CURR" | egrep '(android/.*)|(ios/.*)

Thanks again!
Yeah, it's expected. This snippet just lists files changed between revisions and looks for ones in the ios or android directories.
Most helpful comment
This fixed the issue https://github.com/software-mansion/react-native-reanimated/pull/1496
It is going to be included in the next release.
You can get a package of the current master built daily here.