Failed prop type: Invalid prop `opacity` of type `object` supplied to `RCTView`

Viewed 2830

I'm following the React Native tutorial from: https://facebook.github.io/react-native/docs/animated.html

However, I got the following warning when I ran my code: Failed prop type: Invalid prop opacity of type object supplied to RCTView

And the component just disappear without animation when fade() got called.

And here is a sample code:

import React, { Component } from 'react';
import {
  AppRegistry,
  Text,
  View,
  Animated,
  StyleSheet
} from 'react-native';

import Icon from 'react-native-vector-icon/FontAwesome'

export default class Sample extends Component {
  state = {
    fadeAnim: new Animated.Value(0),
  }
  fade() {
    Animated.timing(                  // Animate over time
      this.state.fadeAnim,            // The animated value to drive
      {
        toValue: 1,                   // Animate to opacity: 1 (opaque)
        duration: 10000,              // Make it take a while
      }
    ).start();                        // Starts the animation
  }
  render() {
    let { fadeAnim } = this.state;

    return (
      <View style={styles.container}>
        <TouchableHighlight onPress={() => {this.fade()}}>
          <Icon name="circle" size={30} color="#fff" style={{opacity: fadeAnim}}
          >
        </TouchableHighlight>
      </View>
    );
  }
......
}
4 Answers

You should change the View to an Animated.View. Then optionally you can add an interpolated value of fadeAnim for more fine grained control.

Something like this should work...

render() {
    const { fadeAnim } = this.state;

    // optionally tweak the input / output range to suit your needs
    const opacity = fadeAnim.interpolate({
      inputRange: [0, 1],
      outputRange: [0, 1]
    });

    return (
      <Animated.View style={[styles.container, opacity]}>
        <TouchableHighlight onPress={() => {this.fade()}}>
          <Icon name="circle" size={30} color="#fff"
          >
        </TouchableHighlight>
      </Animated.View>
    );
  }

You may not want to fade the container view, in which case move the Animated.View inside the Touchable.

I had a similar problem but mine was because I was trying to use a stylesheet object as below

export const Skeleton = () => {
    const opacity = useRef(new Animated.Value(0));
    const styles = StyleSheet.create({
        skeleton: {
            flex: 1,
            backgroundColor: `rgb(210, 210, 210)`,
            position: 'relative',
            borderRadius: Number(borderRadius),
            width: width,
            height: height,
            opacity: opacity.current
        }
    })
    useEffect(() => {
        Animated.loop(
            Animated.sequence([
                Animated.timing(opacityVal, { toValue: 0.3, duration: 500, useNativeDriver: true }),
                Animated.timing(opacityVal, { toValue: 1, duration: 400, useNativeDriver: true  })
            ])
        ).start()
    }, [opacity])
    return (
        <Animated.View style={ styles.skeleton } />
    )
}

So I had to remove opacity from the stylesheet object and add it directly to the JSX like this

return (
    <Animated.View style={[styles.skeleton, { opacity: opacity.current }]} />
)

I kept the other css in the object for readability and used an array in the style prop so I could add the opacity in addition to the other css.

Related