React Native Animated不要在第一次点击上工作
我正在使用 React Native 创建一张扑克桌,我希望点击椅子时会发生动画(椅子围绕桌子排列)。
但是第一次点击时动画不起作用,而当我第二次点击时动画就起作用了。
你可以看到桌子周围有 8 把椅子,我想要的是,每当我点击任何桌子时,旋转应该以我点击的桌子的方式进行应该更换绿色table(bottom)
问题是,第一次单击时,useEffect 中的代码可以工作,但仍然不会发生动画。
这是代码
import {
Animated,
} from 'react-native';
function HomeScreen() {
const [shiftBy, setSiftBy] = React.useState(0);
const [p1InitialPosition] = React.useState(new Animated.ValueXY({ x: 180, y: 30 }));
const [p2InitialPosition] = React.useState(new Animated.ValueXY({ x: 325, y: 125 }));
const [p3InitialPosition] = React.useState(new Animated.ValueXY({ x: 338, y: 230 }));
const [p4InitialPosition] = React.useState(new Animated.ValueXY({ x: 335, y: 370 }));
const [p5InitialPosition] = React.useState(new Animated.ValueXY({ x: 180, y: 470 }));
const [p6InitialPosition] = React.useState(new Animated.ValueXY({ x: 30, y: 370 }));
const [p7InitialPosition] = React.useState(new Animated.ValueXY({ x: 30, y: 230 }));
const [p8InitialPosition] = React.useState(new Animated.ValueXY({ x: 40, y: 125 }));
const chairs = React.useMemo(() => {
return [
p1InitialPosition,
p2InitialPosition,
p3InitialPosition,
p4InitialPosition,
p5InitialPosition,
p6InitialPosition,
p7InitialPosition,
p8InitialPosition,
];
}, [
p1InitialPosition,
p2InitialPosition,
p3InitialPosition,
p4InitialPosition,
p5InitialPosition,
p6InitialPosition,
p7InitialPosition,
p8InitialPosition,
]);
// updated/animated positions
React.useEffect(() => {
const np = [];
for (let i = 0; i < chairs.length; i++) {
console.log(chairs[i], chairs[(i + shiftBy) % 8]);
np.push(
Animated.timing(chairs[i], {
toValue: chairs[(i + shiftBy) % 8],
duration: 800,
useNativeDriver: true,
}),
);
}
Animated.parallel(np).start();
console.log('');
}, [shiftBy]);
return (
<SafeAreaView style={styles.container}>
<Image
onLayout={event => {
const layout = event.nativeEvent.layout;
console.log('height:', layout.height);
console.log('width:', layout.width);
console.log('x:', layout.x);
console.log('y:', layout.y);
}}
source={require('../../assets/image/table/table.png')}
style={{
height: '100%',
width: '100%',
}}
/>
{/* p1 */}
<Animated.View
style={{
position: 'absolute',
transform: [{ translateX: p1InitialPosition.x }, { translateY: p1InitialPosition.y }],
}}>
<TouchableOpacity
// disabled={selectedChair}
onPress={() => setSiftBy(4)}>
<Icon name="chair" size={30} color="blue" />
</TouchableOpacity>
</Animated.View>
{/* p2 */}
<Animated.View
style={{
position: 'absolute',
transform: [{ translateX: p2InitialPosition.x }, { translateY: p2InitialPosition.y }],
}}>
<TouchableOpacity
// disabled={selectedChair}
onPress={() => setSiftBy(3)}>
<Icon name="chair" size={30} color="skyblue" />
</TouchableOpacity>
</Animated.View>
{/* p3 */}
{/* p4 */}
{/* p5 */}
{/* p6 */}
{/* p7 */}
{/* p8 */}
</SafeAreaView>
);
}
export default HomeScreen;
这是完成屏幕代码的链接 - snack.expo.dev/sd7yF5CzZ
请帮忙。
I am creating a poker table using react native and I want that on the click of a chair animation should happen(arrangement of chairs around the table).
But animation does not work on clicking on the first time, while it works when I click 2nd time.
You can see there are 8 chairs around the table what I want is that whenever I click on any table, the rotation should take place in such a way that the table I clicked on should replace the green table(bottom)
The problem is that on the first click, the code inside useEffect works but still animation does not occur.
Here is the code
import {
Animated,
} from 'react-native';
function HomeScreen() {
const [shiftBy, setSiftBy] = React.useState(0);
const [p1InitialPosition] = React.useState(new Animated.ValueXY({ x: 180, y: 30 }));
const [p2InitialPosition] = React.useState(new Animated.ValueXY({ x: 325, y: 125 }));
const [p3InitialPosition] = React.useState(new Animated.ValueXY({ x: 338, y: 230 }));
const [p4InitialPosition] = React.useState(new Animated.ValueXY({ x: 335, y: 370 }));
const [p5InitialPosition] = React.useState(new Animated.ValueXY({ x: 180, y: 470 }));
const [p6InitialPosition] = React.useState(new Animated.ValueXY({ x: 30, y: 370 }));
const [p7InitialPosition] = React.useState(new Animated.ValueXY({ x: 30, y: 230 }));
const [p8InitialPosition] = React.useState(new Animated.ValueXY({ x: 40, y: 125 }));
const chairs = React.useMemo(() => {
return [
p1InitialPosition,
p2InitialPosition,
p3InitialPosition,
p4InitialPosition,
p5InitialPosition,
p6InitialPosition,
p7InitialPosition,
p8InitialPosition,
];
}, [
p1InitialPosition,
p2InitialPosition,
p3InitialPosition,
p4InitialPosition,
p5InitialPosition,
p6InitialPosition,
p7InitialPosition,
p8InitialPosition,
]);
// updated/animated positions
React.useEffect(() => {
const np = [];
for (let i = 0; i < chairs.length; i++) {
console.log(chairs[i], chairs[(i + shiftBy) % 8]);
np.push(
Animated.timing(chairs[i], {
toValue: chairs[(i + shiftBy) % 8],
duration: 800,
useNativeDriver: true,
}),
);
}
Animated.parallel(np).start();
console.log('');
}, [shiftBy]);
return (
<SafeAreaView style={styles.container}>
<Image
onLayout={event => {
const layout = event.nativeEvent.layout;
console.log('height:', layout.height);
console.log('width:', layout.width);
console.log('x:', layout.x);
console.log('y:', layout.y);
}}
source={require('../../assets/image/table/table.png')}
style={{
height: '100%',
width: '100%',
}}
/>
{/* p1 */}
<Animated.View
style={{
position: 'absolute',
transform: [{ translateX: p1InitialPosition.x }, { translateY: p1InitialPosition.y }],
}}>
<TouchableOpacity
// disabled={selectedChair}
onPress={() => setSiftBy(4)}>
<Icon name="chair" size={30} color="blue" />
</TouchableOpacity>
</Animated.View>
{/* p2 */}
<Animated.View
style={{
position: 'absolute',
transform: [{ translateX: p2InitialPosition.x }, { translateY: p2InitialPosition.y }],
}}>
<TouchableOpacity
// disabled={selectedChair}
onPress={() => setSiftBy(3)}>
<Icon name="chair" size={30} color="skyblue" />
</TouchableOpacity>
</Animated.View>
{/* p3 */}
{/* p4 */}
{/* p5 */}
{/* p6 */}
{/* p7 */}
{/* p8 */}
</SafeAreaView>
);
}
export default HomeScreen;
this is the link to complete the code for the screen- snack.expo.dev/sd7yF5CzZ
Please help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
解决方案是在您的代码中添加
uselayouteffect
:解释,
因为
useeffect
在渲染commit phass easte easte e easte east e e e shose east e easter easte e easte east e e e e eptaim evers 在渲染周期和之后被调用layoutanimation.configurenext
是为了“准备”下一个渲染,已经在useffect
的内部称呼它已经为时已晚。因此,解决方案是使用
uselayouteffect
以及usefect
以确保动画在第一次渲染上运行The solution is to add
useLayoutEffect
in your code :Explaination
Since
useEffect
callbacks are called after the render commit phase and hence after the render cycle, andLayoutAnimation.configureNext
is meant to "prepare" the next render, it is already too late to call it inside ofuseEffect
.So the solution is to use
useLayoutEffect
along withuseEffect
to ensure that animation will run on first render