Javascript 如何将React Native animation修复为仅设置动画;这";成分
我有一个tic-tac-toe游戏的Tile课程。我的目标是动画的瓷砖内容的外观,只有最近按下瓷砖的外观。我的问题有两方面: 1:动画仅适用于第一次平铺按压,而不是每次 2:动画将影响所有平铺 编辑:增加Javascript 如何将React Native animation修复为仅设置动画;这";成分,javascript,reactjs,react-native,Javascript,Reactjs,React Native,我有一个tic-tac-toe游戏的Tile课程。我的目标是动画的瓷砖内容的外观,只有最近按下瓷砖的外观。我的问题有两方面: 1:动画仅适用于第一次平铺按压,而不是每次 2:动画将影响所有平铺 编辑:增加value.setValue(0)至使用effect()重置每次按下的动画值。剩下的唯一问题是,所有的平铺组件在每次按下时都会产生动画,而我只希望组件的道具内容发生了变化 如果我将Animated.timing函数放在onSelection中,则只有按下的才按预期进行动画制作,但由于这是通过套接
value.setValue(0)
至使用effect()
重置每次按下的动画值。剩下的唯一问题是,所有的平铺组件在每次按下时都会产生动画,而我只希望
组件的道具内容发生了变化
如果我将Animated.timing
函数放在onSelection
中,则只有按下的才按预期进行动画制作,但由于这是通过套接字连接进行的,因此两个客户端的互动程序都需要进行动画制作,在这种情况下,只有按下互动程序的客户端才能看到动画。(因为动画功能不再在useffect()
中)
编辑2:尝试更改useffect()
以包括依赖项数组和条件语句,以及仅包括中引用的依赖项数组
Tile.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;
import React,{useffect,useState}来自“React”;
从“./SocketContext”导入SocketContext;
从“react native”导入{View,动画,TouchableOpacity};
从“./资源/样式/主样式”导入样式;
功能瓷砖(道具){
函数onSelection(行、列、套接字){
选择道具(行、列、插座);
}
让[value]=useState(新的动画.value(0));
//useffect(()=>{
//设置值(0);
//动画。计时(值{
//toValue:100,
//持续时间:10000,
//useNativeDriver:真的吗
//})启动();
// });
(编辑2-a):
useffect(()=>{
if(props.contents!={marker:null}){
返回
}否则{
设置值(0);
动画。计时(值{
toValue:100,
持续时间:10000,
useNativeDriver:真的吗
}).start();
}
},[道具内容];
(编辑2-b):
useffect(()=>{
设置值(0);
动画。计时(值{
toValue:100,
持续时间:10000,
useNativeDriver:真的吗
}).start();
},[道具内容];
让动画_不透明度=value.interpolate({
输入范围:[01100],
输出范围:[0.0,1.0]
});
让动画旋转=value.interpolate({
输入范围:[0,50,100],
输出范围:[“0度”、“180度”、“360度”]
});
返回(
{socket=>(
onSelection(props.row、props.col、socket)}
>
{props.contents.marker}
)}
);
}
导出默认瓷砖;
如何在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;
从“React”导入React;
从“react native”导入{View};
从“./组件/磁贴”导入磁贴;
从“./资源/样式/主样式”导入样式;
功能网格(道具){
功能选择(行、列、套接字){
道具选择(行、列、插座);
}
const grid=props.grid.map((行,行)=>{
常量单元格=rowEl.map((单元格,列)=>{
返回(
);
});
返回(
{cells}
);
});
返回{grid};
}
导出默认网格;
我的目标是在每次按下互动程序时,当互动程序的props.contents
发生变化时运行动画,并且仅针对该互动程序。我不确定是否每次按下一个新的平铺时整个网格(props.grid
)都会被重新渲染,这就是为什么会创建这个不需要的功能
但是,动画仅在第一次按平铺时运行。它对棋盘上的每个磁贴都运行(我知道这一点,因为我有一个问题,以前的游戏内存泄漏到新游戏~另一个问题)现在,您的useffect
将在每个渲染上运行,因为它没有任何作为第二个参数提供的依赖项。另一个问题是跳过第一次渲染时的效果
如果平铺内容标记的初始值为null,则可以使用以下方法解决此问题:
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]);
有关useffect
的第二个参数的更多信息,请参阅。我不完全理解这个问题。是所有的都在同一时间运行还是只运行第一个?两者都有。我知道它会为所有现有的
组件设置动画,因为存在一个错误,以前的游戏磁贴位置会在新游戏的第一个磁贴选择中溢出。然后,所有瓷砖的外观都将设置动画。这只是第一次按下,动画runstry将键添加到Grid.js
中的平铺
。不过,很好的一点是,它并没有帮助仅动画当前按下的平铺有用信息,链接提醒了我有关依赖关系数组的信息。所以我尝试了你的建议,没有任何改变。动画仍然在每个人的文本上运行。文档说“React将比较上一次渲染的[5]和下一次渲染的[5]。因为数组中的所有项目都相同(5==5),React将跳过效果。”因此我还尝试在没有条件的情况下添加[props.contents]
。这也不管用。动画仍然为所有人播放tiles@Jim请参阅上面的编辑,以使用props.content.marker作为依赖项,并在该值为null时跳过效果。我相信你发布的其他编辑有问题,因为对对象进行严格的平等性检查,这是基于对象标识而不是值进行评估的。e、 g.constobj={key:'val'};obj=={key:'val'}
为false,因此根据{marker:null}
检查您的条件将无效。如果contents.marker是一个标量值,那么我认为我的编辑应该解决这个问题。