首页 > 解决方案 > React 本机状态未使用 animated.start() 中的钩子更新

问题描述

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)。如果有人知道问题出在哪里,请帮助我。谢谢。

标签: javascriptreactjsreact-nativereact-state

解决方案


推荐阅读