Reagents - Animated Functional Components

I love the animated React Native API, but it conflicts strongly with my preferred way of writing components, which are fully functional stateless components.

Take this component as an example. How do I animate an image without going back to the class syntax and state variable to control the image style?

const Logo = () => (
  <View style={styles.container}>
    <View style={styles.imageContainer}>
      <Animated.Image 
        resizeMode='contain'
        style={styles.image}
        source={require(img/sample.png')}
      />
    </View>
  </View>
)

export default Logo

      

+6


source to share


2 answers


You can use the store to save the animated values, of course. But IMO this is a bad idea. Just use classes. You should be more flexible;)

Alternatively, you can try https://github.com/oblador/react-native-animatable with declarative syntax. I haven't used it before, but it looks like it might help.



UPDATED: As of React Native 0.59 and up, you can use hooks inside functional components.

+6


source


As mentioned, you can use react hooks. They were introduced in React 16.8 and added to React Native in version 0.59.

You will have to use useState

and useEffect

.

const AnimatedComponent = (props)=>{

    // Need to create state first. Setter is not used in this case
    const [value] = useState(new Animated.Value(props.value))

    useEffect(()=>{
        Animated.timing(value, {
            toValue: props.value,
            duration: 100,
        }).start() // < Don't forget to start!
    }, [props.value]) // < Run animation only when props.value changed

    // Apply animated property to your style
    return (
        <Animated.View style={{width: value}} />
    )
}

      




For example, this is how I implemented the progress bar:

const ProgressBar = (props)=>{

    const [value] = useState(new Animated.Value(props.value))

    useEffect(()=>{
        Animated.timing(value, {
            toValue: props.value,
            duration: 100,
        }).start()
    }, [props.value])

    const width = value.interpolate({
        inputRange: [0, 100],
        outputRange: ['0%', '100%'],
    })

    return (
        <View style={{
            width: '100%',
            height: '100%',
            flexDirection: 'row',
            backgroundColor: 'white',
        }}>
            <Animated.View style={{
                width: width,
                height: '100%',
                backgroundColor: 'green',
            }}></Animated.View>
        </View>
    )
}

      

UPTADED

+2


source







All Articles