Собственное состояние React не обновляется с помощью хуков в animated.start () - PullRequest
0 голосов
/ 06 августа 2020
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). Пожалуйста, помогите мне, если кто-нибудь знает, где проблема. Спасибо.

...