如何修复 React-Native 动画以仅动画“这个”组件

Jim*_*Jim 5 javascript reactjs react-native

我在井字棋游戏中有一个瓷砖类。我的目标是为磁贴内容的外观设置动画,并且只显示最近按下的磁贴的外观。我的问题有两个:1:动画仅适用于第一次按瓷砖,而不是每次都适用 2:动画影响所有瓷砖

编辑:添加value.setValue(0);useEffect()每次按下重置动画值。唯一剩下的问题是所有 Tile 组件在每次按下时都会动画,而我只希望更改的<Tile>组件有动画props.contents

如果我改为将Animated.timing函数放入onSelection,则只有按下的动画会按预期进行,但由于这是通过套接字连接,因此两个客户端的图块都需要动画,在这种情况下,只有按下图块的客户端才能看到动画。(因为动画功能已经不在了useEffect()

编辑 2:尝试更改useEffect()以包含依赖项数组和条件语句以及仅包含https://reactjs.org/docs/hooks-effect.html 中引用的依赖项数组

瓷砖.js

import React, { useEffect, useState } from "react";
import SocketContext from "../socket-context";
import { View, Animated, TouchableOpacity } from "react-native";
import styles from "../assets/styles/main-style";

function Tile(props) {
  function onSelection(row, col, socket) {
    props.onSelection(row, col, socket);
  }
  let [value] = useState(new Animated.Value(0));

  // useEffect(() => {
  //  value.setValue(0);
  //  Animated.timing(value, {
  //    toValue: 100,
  //    duration: 10000,
  //    useNativeDriver: true
  //  }).start();
  // });

  (EDIT 2-a):
   useEffect(() => {
    if (props.contents !== {marker: null}) {
      return
    } else {
     value.setValue(0);
     Animated.timing(value, {
       toValue: 100,
       duration: 10000,
       useNativeDriver: true
     }).start();
    }
   }, [props.contents]);

  (EDIT 2-b):
   useEffect(() => {
     value.setValue(0);
     Animated.timing(value, {
       toValue: 100,
       duration: 10000,
       useNativeDriver: true
     }).start();
   }, [props.contents]);

  let animated_opacity = value.interpolate({
    inputRange: [0, 100],
    outputRange: [0.0, 1.0]
  });

  let animated_rotation = value.interpolate({
    inputRange: [0, 50, 100],
    outputRange: ["0deg", "180deg", "360deg"]
  });

  return (
    <SocketContext.Consumer>
      {socket => (
        <View style={styles.grid_cell}>
          <TouchableOpacity
            style={styles.cell_touchable}
            onPress={() => onSelection(props.row, props.col, socket)}
          >
            <Animated.Text
              style={{
                fontFamily: "BungeeInline-Regular",
                fontSize: 65,
                textAlign: "center",
                color: "#fff",
                opacity: animated_opacity,
                transform: [{ rotateX: animated_rotation }]
              }}
            >
              {props.contents.marker}
            </Animated.Text>
          </TouchableOpacity>
        </View>
      )}
    </SocketContext.Consumer>
  );
}

export default Tile;
Run Code Online (Sandbox Code Playgroud)

如何在 Grid.js 中使用 Tile

import React from "react";
import { View } from "react-native";
import Tile from "../components/Tile";
import styles from "../assets/styles/main-style";

function Grid(props) {
  function onGridSelection(row, col, socket) {
    props.onGridSelection(row, col, socket);
  }

  const grid = props.grid.map((rowEl, row) => {
    const cells = rowEl.map((cellEl, col) => {
      return (
        <Tile
          row={row}
          col={col}
          contents={cellEl}
          onSelection={onGridSelection}
        />

      );
    });
    return (
      <View style={styles.grid_row} key={row}>
        {cells}
      </View>
    );
  });
  return <View style={styles.grid}>{grid}</View>;
}

export default Grid;
Run Code Online (Sandbox Code Playgroud)

我的目标是让动画在瓷砖props.contents发生变化时运行,每次按下瓷砖时,并且针对该瓷砖。我不确定props.grid每次按下新图块时整个网格 ( ) 是否都被重新渲染,这是否以某种方式创建了这个不需要的功能。

然而,动画在第一次瓷砖印刷时运行。它为板上的每个图块运行(我知道这一点,因为我有一个问题,以前的游戏内存泄漏到新游戏〜一个单独的问题)

azu*_*ndo 3

现在,您useEffect在每个渲染上运行,因为它没有作为第二个参数提供的任何依赖项。另一个问题是跳过第一次渲染的效果。

如果图块内容标记的初始值为空,那么您可以使用以下方法解决此问题:

  useEffect(() => {
    // exit early if the Tile contents are the initial content values
    // which means the animation shouldn't run
    if (props.contents.marker === null) {
      return;
    }
    value.setValue(0);
    Animated.timing(value, {
      toValue: 100,
      duration: 10000,
      useNativeDriver: true
    }).start();
  // note the addition of the dependency array here so this effect only runs
  // when props.contents.marker changes
  }, [props.contents.marker]);
Run Code Online (Sandbox Code Playgroud)

有关 的第二个参数的更多信息,请参阅https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effectsuseEffect