react-spring: [react-native] Animated transform not working

I see there’s #360 and #361, but it’s not working for me on latest version. Maybe there was a regression?

I’m using latest version with hooks (^7.2.8). React Native 0.57.4 with hooks enabled.

import {View } from 'react-native'
import { animated, useTransition } from 'react-spring/hooks'

const AnimatedView = animated(View) // also tried animated(Animated.View)

This doesn’t work

// ...
    from: { width: 0 },
    enter: { width: size },
    leave: { width: 0 },
// ...

<AnimatedView style={{ transform: [{ translateX: transition.props.width }] }}>

You passed an Animated.Value to a normal component

This doesn’t work

// ...
    from: { transform: [{ translateX: 0 }] },
    enter: { transform: [{ translateX: size }] },
    leave: { transform: [{ translateX: 0 }] },
// ...

<AnimatedView style={transition.props}>

Invariant Violation: You must specify exactly one property per transform object

Just for reference, these work:

<AnimatedView style={{ width: transition.props.width }}>
<Animated.View style={{ transform: [{ translateX: new Animated.Value(100) }] }}>

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 5
  • Comments: 21 (9 by maintainers)

Most upvoted comments

The following worked for me on iOS, Android and Web on a react-native-web app using both react-spring 8.0.19 and 9.0.0-beta.1. I believe it should work on a react-native only app too:

import React from "react";
import { View } from "react-native";
import { animated, useSpring } from "react-spring/native";

export default () => {
  const style = {
    backgroundColor: "red",
    height: 100,
    width: 100
  };

  const motionProps = useSpring({
    translateY: 200,
    from: { translateY: 20 }
  });
  const motionStyle = {
    ...style,
    transform: [{ translateY: motionProps.translateY }]
  };

  const AnimatedView = animated(View);

  return (
    <View>
      <AnimatedView style={motionStyle} />
    </View>
  );
};

If anyone can double check this please let us know how it goes.

This has worked for me:

import from native

import { animated, useSpring } from 'react-spring/native'; <----------------
import { View } from 'react-native';

const AnimatedView = animated(View);

then

  const style = useSpring({
    from: { translateY: -500 },
    to: async next => {
      await next({ translateY: 10 });
      await next({ translateY: -500, delay: 100 });
    },
  });

  return (
    <AnimatedView style={{ transform: [{ translateY: style.translateY }] }}>
      {component}
    </AnimatedView>
  );

@sebinsua Animating arrays of objects is not supported:

  const transitions = useTransition(index, p => p, {
    from: { opacity: 0, transform: [{ translate: ['100%', 0, 0] }] },
    enter: { opacity: 1, transform: [{ translate: ['0%', 0, 0] }] },
    leave: { opacity: 0, transform: [{ translate: ['-50%', 0, 0] }] },
  });

Animate the strings (eg: -50%) instead and use them like this:

<AnimatedPage style={{ transform: [{ translateX: props.translateX }] }} />

found a solution with interpolate, just return to whole array like so: transform: move.interpolate(m => [{ translateX: m }])

@aleclarson Thanks! This worked when I started to use number values.

However, I have one more problem - the leave animation is not playing (the new commit in the repository demonstrates this). I was expecting the current page to move right at the same time as the new page moves from the left as worked in the example for the web (thought opposite directions). Any ideas? position: absolute fixed this!