【问题标题】:How to animate width of native-react component?如何为原生反应组件的宽度设置动画?
【发布时间】:2026-01-22 03:45:02
【问题描述】:

我正在使用动画 API import { Animated } from 'react-native'

在样式中指定width: animated-value 时,width 实际上只渲染一次,并且不会动态更改。如果您使元素重新渲染,您只能看到幕后的动画值正在发生变化。

// since only function components can use hooks, wrap the classical component in a function one
// that sets up the hook for it
function withAnimationHook(Component) {
  return function WrappedComponent(props) {
    const anim = useRef(new Animated.Value(0));
    useEffect(() => {
      Animated.loop(
        Animated.sequence([
          Animated.timing(anim.current, {
            toValue: 1, 
            duration: 2000,
          }),
          Animated.timing(anim.current, {
            toValue: 0, 
            duration: 2000,
          }),
        ])
      ).start();
    }, []);
    return <Component {...props} anim={anim} />;
  }
}

class AnimatedButton extends React.Component {
  render() {
    const { anim, width } = this.props
    return (
      <Animated.View style={{  width: width * anim.current._value }}>
      </Animated.View>
    )
  }
}

export default withAnimationHook(AnimatedButton)

我知道设置动画值是可行的,因为 style={{ transform: [{ scale: anim.current }] }} 可以完美运行(它会反复增长和缩小)。

为什么width: width * anim.current._value 不对宽度设置动画?

如何为宽度设置动画?

this.props.width 只是一个数字,例如64

【问题讨论】:

    标签: javascript react-native react-native-web


    【解决方案1】:

    试试这个。

    const SubView = ({ parentValue = 0, propWidth=2000 }) => {
      const animatedValue = useRef(new Animated.Value(0)).current
    
      useEffect(() => {
        Animated.timing(animatedValue, {
          toValue: parentvalue,
          duration: 2000,
        }).start()
      }, [parentValue])
    
      return (
        <Animated.View
          style={[
            styles.viewStyle,
            {
              width: animatedValue.interpolate({
                inputRange: [0, 1],
                outputRange: [0, propWidth],
              }),
            },
          ]}
        ></Animated.View>
      )
    }
    
    export default React.memo(SubView)
    

    【讨论】:

    • 唯一重要的变化是使用.interpolate 对吗?您答案中的其余代码似乎对答案并不重要
    • 应该是 width * anim.current._value 而不是 anim.current.interpolate({ inputRange: [0, 1], outputRange: [0, width] })
    • 是的,并且在您的代码中 这行不起作用。并且您的 useEffect 函数只运行一次。因为 [] 是空的。 useEffect(() => { }, []);