React Native - 动画功能组件

Bri*_*n F 6 reactjs react-native

我喜欢React Native动画API,但它与我首选的编写组件的方式有很大冲突,这些组件是完全无状态的功能组件.

以此组件为例.如何在不恢复类语法和状态变量来驱动图像样式的情况下使图像动画化?

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
Run Code Online (Sandbox Code Playgroud)

tei*_*vaz 20

正如 farwayer 提到的,您可以使用反应钩子。它们是在 React 16.8 中引入的,并在 0.59 版中添加到 React Native 中。

您将必须同时使用useStateuseEffect

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}} />
    )
}
Run Code Online (Sandbox Code Playgroud)

例如,这是我实现进度条的方式:

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>
    )
}
Run Code Online (Sandbox Code Playgroud)

更新

  • 这看起来像是对 useState 的滥用,不是吗?您直接改变状态变量,而不是通过 useState。这样做可能会更好:````const value = useRef(new Animated.Value(0)).current``` (4认同)

far*_*yer 6

您可以使用商店来保持动画值.但IMO这是个坏主意.只需使用课程.你应该更灵活;)

作为替代方案,您可以使用声明性语法尝试https://github.com/oblador/react-native-animatable.我以前没有使用它,但看起来它可以帮助.