问题描述
场景:我在屏幕上呈现了一个 svg circle
和一个 state
。我也有两个按钮。 Change Size
按钮将圆圈的大小(共享值)从 50 更改为 100 或 100 更改为 50。更改状态按钮将状态从“apple”更改为“orange”或“orange”更改为“apple”。
[注意:动画不以任何方式使用状态。我也在每次重新渲染时控制台记录 size.value
]
问题:按下 Change Size
按钮后,它会将圆圈从 50 动画化到 100。现在,如果您按下 Change State
按钮,它会更改状态,但它也会尽管我们的日志显示共享值 size.value
仍为 100,但使圆的大小恢复为 50。
预期行为:预期圆圈的大小保持为 100,因为这是提供给圆圈的共享值。
代码:
import React,{useState,useEffect} from 'react';
import { Text,View,Button} from 'react-native';
import Animated,{
useAnimatedProps,useSharedValue,withSpring,} from 'react-native-reanimated';
import Svg,{Circle} from 'react-native-svg';
const App = () => {
const [state,setState] = useState('apple');
const size = useSharedValue(50);
const animatedProps = useAnimatedProps(() => {
return {
r: size.value / 2,};
});
const AnimatedCircle = Animated.createAnimatedComponent(Circle);
useEffect(() => {
console.log('size.value =',size.value);
});
return (
<View style={{flex: 1}}>
<Svg height={100} width={100}>
<AnimatedCircle
cx="50"
cy="50"
fill="green"
animatedProps={animatedProps}
/>
</Svg>
<Text>{state}</Text>
<Button
title="Change Size"
onPress={() => {
size.value = withSpring(size.value === 50 ? 100 : 50);
}}
/>
<Button
title="Change State"
onPress={() => {
setState(state === 'apple' ? 'orange' : 'apple');
}}
/>
</View>
);
}
export default App;
任何帮助将不胜感激?
解决方法
只需将 const AnimatedCircle = Animated.createAnimatedComponent(Circle);
移到函数组件之外。因为,在每次渲染时,react 都会运行您的函数。由于 createAnimatedComponent 在您的函数体中,它也会重新运行,因此它会从头开始再次创建组件。但是您应该创建一次组件。
import React,{useState,useEffect} from 'react';
import { Text,View,Button} from 'react-native';
import Animated,{
useAnimatedProps,useSharedValue,withSpring,} from 'react-native-reanimated';
import Svg,{Circle} from 'react-native-svg';
const AnimatedCircle = Animated.createAnimatedComponent(Circle);
const App = () => {
const [state,setState] = useState('apple');
const size = useSharedValue(50);
const animatedProps = useAnimatedProps(() => {
return {
r: size.value / 2,};
});
useEffect(() => {
console.log('size.value =',size.value);
});
return (
<View style={{flex: 1}}>
<Svg height={100} width={100}>
<AnimatedCircle
cx="50"
cy="50"
fill="green"
animatedProps={animatedProps}
/>
</Svg>
<Text>{state}</Text>
<Button
title="Change Size"
onPress={() => {
size.value = withSpring(size.value === 50 ? 100 : 50);
}}
/>
<Button
title="Change State"
onPress={() => {
setState(state === 'apple' ? 'orange' : 'apple');
}}
/>
</View>
);
}