import React, { useRef, useState, useEffect } from "react";
import {
Animated,
Dimensions,
View,
StyleSheet,
PanResponder,
Text,
Image,
} from "react-native";
import { catarray } from "./categoryimages";
const { width, height } = Dimensions.get("screen");
const App = () => {
const pan = useRef(new Animated.ValueXY()).current;
const [currentIndex, setCurrentIndex] = useState(0);
const rotate = pan.x.interpolate({
inputRange: [-width / 2, 0, width / 2],
outputRange: ["-10deg", "0deg", "10deg"],
extrapolate: "clamp",
});
useEffect(() => {
pan.setValue({ x: 0, y: 0 });
}, [currentIndex]);
const nextCardOpacity = pan.x.interpolate({
inputRange: [-width / 2, 0, width / 2],
outputRange: [1, 0, 1],
extrapolate: "clamp",
});
const nextCardScale = pan.x.interpolate({
inputRange: [-width / 2, 0, width / 2],
outputRange: [1, 0.8, 1],
extrapolate: "clamp",
});
const renderImages = () => {
let rotateandtranslate = {
transform: [{ rotate: rotate }, ...pan.getTranslateTransform()],
};
return catarray
.map((item, index) => {
if (index < currentIndex) {
return null;
} else if (index === currentIndex) {
return (
<Animated.View
key={index}
style={[
rotateandtranslate,
{
width: width * 0.9,
height: height * 0.85,
position: "absolute",
},
]}
{...panResponder.panHandlers}
>
<Image
source={{ uri: item.uri }}
style={{
flex: 1,
height: null,
width: null,
borderRadius: 30,
}}
/>
</Animated.View>
);
} else {
return (
<Animated.View
key={index}
style={[
{
opacity: nextCardOpacity,
transform: [{ scale: nextCardScale }],
},
{
width: width * 0.9,
height: height * 0.85,
position: "absolute",
},
]}
>
<Image
source={{ uri: item.uri }}
style={{
flex: 1,
height: null,
width: null,
borderRadius: 30,
}}
/>
</Animated.View>
);
}
})
.reverse();
};
const panResponder = useRef(
PanResponder.create({
onMoveShouldSetPanResponder: () => true,
onPanResponderGrant: () => {
pan.setOffset({
x: pan.x._value,
y: pan.y._value,
});
},
onPanResponderMove: Animated.event([null, { dx: pan.x, dy: pan.y }]),
onPanResponderRelease: (e, gestureState) => {
if (gestureState.dx > 140) {
Animated.spring(pan, {
toValue: { x: width + width, y: gestureState.dy },
}).start(() => {
setCurrentIndex(currentIndex + 1);
});
} else if (gestureState.dx < -140) {
Animated.spring(pan, {
toValue: { x: -width - width, y: gestureState.dy },
}).start(() => {
setCurrentIndex(currentIndex + 1);
});
} else {
Animated.spring(pan, {
toValue: { x: 0, y: 0 },
friction: 2,
}).start();
}
},
})
).current;
return <View style={styles.container}>{renderImages()}</View>;
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
},
titleText: {
fontSize: 14,
lineHeight: 24,
fontWeight: "bold",
},
box: {
height: 150,
width: 150,
backgroundColor: "blue",
borderRadius: 5,
},
});
export default App;
Я пробовал анимацию смахивания тиндера. реагирует на собственные хуки, и все работает нормально для первых двух карт. Но после этого currentIndex остается на "1" и не обновляется. Но я обнаружил, что значение currentIndex каким-то образом переинициализируется на 0. Значение currentIndex не обновить, хотя я звоню setCurrentIndex(currentIndex+1)
. Пожалуйста, помогите мне, если кто-нибудь знает, где проблема. Спасибо.