I'm trying to use a SharedValue from react-native-reanimated2 to store an object (box positions). The object is of the following shape:
boxPositions.value = {
[boxId]: {x: 0, y: 0}
...
}
My goal is to update the object in the SharedValue so that it animates a specific box's position given its id
.
To update a box's position, I'm doing the following, and applying withSpring()
to the object's y
property to have it animate:
const moveRandomBox = () => {
const randId = Math.floor(Math.random() * boxes.length) + 1;
boxPositions.value = {
...boxPositions.value,
[randId]: {
x: boxPositions.value[randId].x,
y: withSpring(boxPositions.value[randId].y - 50)
}
};
}
I'm then passing this shared value object to my box component itself, and then creating an animated style to transform the box's position:
const rStyle = useAnimatedStyle(() => {
const boxPosition = boxPositions.value[box.id] ? ? {x: 0, y: 0};
return {
transform: [
{translateX: boxPosition.x},
{translateY: boxPosition.y} // this value should be animated
]
};
}, []);
The problem is that this approach of applying the withSpring()
animation causes the box to not move at all when moveRandomBox()
is called.
However, if I change the moveRandomBox()
function to set the y
position to a plain value:
[randId]: {
x: boxPositions.value[randId].x,
y: boxPositions.value[randId].y - 50 // instead of: withSpring(boxPositions.value[randId].y - 50)
}
and then change the useAnimatedStyle()
hook to use the withSpring()
animation method, it works as expected:
return {
transform: [
{translateX: boxPosition.x},
{translateY: withSpring(boxPosition.y)} // instead of just: boxPosition.y
]
};
In my actual code I don't want to actually do this, as I have different places where I set my box's x
and y
positions, and I want the animation to be different and not always the same. So I want the animation to be set when I update the box's position (like in the first appraoch), and not in the style definition (second example).
My question is: Why does the first approach of setting the animation not work, whereas the second does? What is wrong with the first approach that stops it from working? How would I go about making the first approach work? I only seem to experience this issue when the SharedValue is an object, setting a SharedValue to an individual withSpring()
value seems to work correctly.
Runnable Example:
To reproduce, change the preview to iOS. Once loaded, click the button "Move random box", and you'll see none of the boxes move. If you change the code to call withSpring()
in the useAnimatedStyle()
hook like above and remove the withSpring()
call from the moveRandomBox()
method you'll see that the box does move.