首页 > 解决方案 > 如何在接收道具时更改 React Native 动画序列时间

问题描述

我有一个循环动画,我希望用户能够更改其时间。我使用 redux 进行了设置,以便当用户在设置中更改它们时,被动画的组件接收新的计时作为道具。然而,这不会改变序列的时间(我猜这是因为序列分配了变量的值,而不是引用改变的变量的值)

class BreatheCircle extends React.Component {
      state = {
            circleAnimation: new Animated.Value(0.6),
            holdAnimation: new Animated.Value(0),
            inhaleAnimation: new Animated.Value(0),
            exhaleAnimation: new Animated.Value(0),
        }
        componentWillReceiveProps(nextProps){
          console.log('next props:', nextProps)
        }

breathAnimation = 
    Animated.loop(
      Animated.sequence([
      Animated.timing(this.state.inhaleAnimation, {toValue: 1, duration:10}),
      Animated.timing(this.state.circleAnimation, {toValue: 1, duration:this.props.in*1000}),
      Animated.timing(this.state.inhaleAnimation, {toValue: 0, duration:10}),
      Animated.timing(this.state.holdAnimation, {toValue: 1, duration:10}),
      Animated.timing(this.state.holdAnimation, {toValue: 0, duration:10, delay: this.props.hold*1000}), //delay for the hold to disappear
      Animated.timing(this.state.exhaleAnimation, {toValue: 1, duration:10}),
      Animated.timing(this.state.circleAnimation, {toValue: 0.6, duration:this.props.out*1000}),
      Animated.timing(this.state.exhaleAnimation, {toValue: 0, duration:10}),
]))


componentDidMount(){
  // this.state.animated.setValue(0.6) // state already declare
  this.animateCircle();
}
componentWillUnmount(){
  this.breathAnimation.stop();
}

animateCircle(){
    this.breathAnimation.start();
}


  render(){
    const{animated} = this.state;
    return(
        <View style={{alignItems: 'center'}}>
        <Animated.View style={{
          width: 350,
          height: 350,
          borderRadius: 200,
          transform: [ {scale: this.state.circleAnimation} ]
        }}>
          <LinearGradient colors={['rgb(255, 206, 224)', 'rgb(248, 120, 131)']} style={{ alignItems: 'center', justifyContent: 'center', flex: 1, borderRadius: 200}}>
            <Animated.Text style={{
              position: 'absolute',
              justifyContent: 'center',
              fontSize: 80,
              fontWeight: 'bold',
              color: 'white',
              opacity: this.state.holdAnimation.interpolate({
                inputRange: [0, 1],
                outputRange: [0, 1],
                extrapolate: 'clamp',
                                },)
                              }}>Hold</Animated.Text>
            <Animated.Text style={{
              position: 'absolute',
              justifyContent: 'center',
              fontSize: 80,
              fontWeight: 'bold',
              color: 'white',
              opacity: this.state.inhaleAnimation.interpolate({
                inputRange: [0, 1],
                outputRange: [0, 1],
                extrapolate: 'clamp',
                                },)
                              }}>Inhale</Animated.Text>
            <Animated.Text style={{
              position: 'absolute',
              justifyContent: 'center',
              fontSize: 80,
              fontWeight: 'bold',
              color: 'white',
              opacity: this.state.exhaleAnimation.interpolate({
                inputRange: [0, 1],
                outputRange: [0, 1],
                extrapolate: 'clamp',
                                },)
                              }}>Exhale</Animated.Text>
          </LinearGradient>
        </Animated.View>
      </View>
    )
  }
}

const mapStateToProps = state => {
  return {
    in: state.in,
    hold: state.hold,
    out: state.out,
  };
};

  export default connect(
    mapStateToProps
  )(BreatheCircle);

当新道具传递给它时,我将如何改变时间?

标签: reactjsreact-nativereact-reduxreact-animatedreact-animations

解决方案


我建议您使用生命周期方法componentDidUpdate:如果您的mapStateToProps工作正常,您可以像这样简单地更新组件的状态:

componentDidUpdate(previousProps, previousState) {
  if (this.props !== previousProps){
    this.setState({
      ... // update your component state with the props you passed here
    })
  }
}

这是文档


推荐阅读