如何让我的删除按钮连续多次从状态中删除项目?
How can I get my delete button to remove items from state more than once consecutively?
抱歉措辞混乱,但我会尽力解释。这是相关的代码块。这个想法是接受键盘输入,并将其添加到保存在状态中的数组中。它部分起作用,因为当我单击一个键时,它会添加到状态数组中。当我单击删除时,它通过复制数组删除最后一项,删除最后一项,然后覆盖整个原始状态。
问题来了。如果再次单击删除,则不会发生任何事情。我猜它与 react 而不是重新渲染有关,但我是个菜鸟所以 idk.
这里有一个 link 到 expo 上的项目,看它的价值(你显然看不到控制台日志)。抱歉鲜艳的颜色,帮助我的菜鸟大脑把事情分开。
https://expo.dev/@qtheginger/projects/Wordley
任何帮助将不胜感激,谢谢!
import React, { useState, useContext } from "react";
import { View, Text, Pressable, StyleSheet, Alert } from "react-native";
import Key from "./Key.js";
import KeyName from "../data/KeyName.json";
import { GameContext } from "../util/gameContext.js";
const styles = StyleSheet.create({
keyBoard: {
flex: 1,
justifyContent: "space-around",
},
keyBoardLine: {
flex: 1,
flexDirection: "row",
justifyContent: "space-around",
// height: "80%",
},
});
export default () => {
const { keyVal, setKeyVal } = useContext(GameContext);
const { cardVal, setCardVal } = useContext(GameContext);
let rowOne = [];
let rowTwo = [];
let rowThree = [];
const keyValSetter = (keyName) => {
setKeyVal(keyName);
};
const cardValSetter = (keyName) => {
setCardVal([...cardVal, keyName]);
};
const combiner = (keyName) => {
keyValSetter(keyName);
if (keyName !== "Delete") {
cardValSetter(keyName);
} else {
const newArr = cardVal;
newArr.pop();
setCardVal(newArr);
}
};
// loop through keyName to display keyboard
for (let i = 0; i < KeyName.length; i++) {
x = i;
if (i < 10) {
rowOne.push(
<Key onPress={() => combiner(KeyName[i])} key={i} index={i} />
);
} else if (i === 10 || i < 19) {
rowTwo.push(
<Key onPress={() => combiner(KeyName[i])} key={i} index={i} />
);
} else {
rowThree.push(
<Key onPress={() => combiner(KeyName[i])} key={i} index={i} />
);
}
}
console.log(keyVal);
console.log(cardVal);
return (
<>
<View style={styles.keyBoard}>
<View style={styles.keyBoardLine}>{rowOne}</View>
<View style={styles.keyBoardLine}>{rowTwo}</View>
<View style={styles.keyBoardLine}>{rowThree}</View>
</View>
</>
);
};
是的,当从状态中删除时,您正在改变它而不是返回一个新数组。
const { cardVal, setCardVal } = useContext(GameContext);
...
const combiner = (keyName) => {
keyValSetter(keyName);
if (keyName !== "Delete") {
cardValSetter(keyName);
} else {
const newArr = cardVal; // <-- reference to state
newArr.pop(); // <-- mutation!!
setCardVal(newArr); // <-- state reference back into state
}
};
cardVal
状态似乎从来都不是更新的数组引用。由于状态引用从未改变,因此 React 假定状态仍然相同并且不会触发重新渲染。
使用功能状态更新从以前的状态正确更新(而不是范围内关闭的任何状态),并将状态浅复制到新的数组引用中。
示例:
const combiner = (keyName) => {
keyValSetter(keyName);
if (keyName !== "Delete") {
cardValSetter(keyName);
} else {
setCardVal(cards => cards.slice(0, -1)) // <-- copy all but last element
}
};
同样,cardValSetter
也应该使用功能状态更新来更新以前的状态。
const cardValSetter = (keyName) => {
setCardVal(cardVal => [...cardVal, keyName]);
};
抱歉措辞混乱,但我会尽力解释。这是相关的代码块。这个想法是接受键盘输入,并将其添加到保存在状态中的数组中。它部分起作用,因为当我单击一个键时,它会添加到状态数组中。当我单击删除时,它通过复制数组删除最后一项,删除最后一项,然后覆盖整个原始状态。
问题来了。如果再次单击删除,则不会发生任何事情。我猜它与 react 而不是重新渲染有关,但我是个菜鸟所以 idk.
这里有一个 link 到 expo 上的项目,看它的价值(你显然看不到控制台日志)。抱歉鲜艳的颜色,帮助我的菜鸟大脑把事情分开。 https://expo.dev/@qtheginger/projects/Wordley
任何帮助将不胜感激,谢谢!
import React, { useState, useContext } from "react";
import { View, Text, Pressable, StyleSheet, Alert } from "react-native";
import Key from "./Key.js";
import KeyName from "../data/KeyName.json";
import { GameContext } from "../util/gameContext.js";
const styles = StyleSheet.create({
keyBoard: {
flex: 1,
justifyContent: "space-around",
},
keyBoardLine: {
flex: 1,
flexDirection: "row",
justifyContent: "space-around",
// height: "80%",
},
});
export default () => {
const { keyVal, setKeyVal } = useContext(GameContext);
const { cardVal, setCardVal } = useContext(GameContext);
let rowOne = [];
let rowTwo = [];
let rowThree = [];
const keyValSetter = (keyName) => {
setKeyVal(keyName);
};
const cardValSetter = (keyName) => {
setCardVal([...cardVal, keyName]);
};
const combiner = (keyName) => {
keyValSetter(keyName);
if (keyName !== "Delete") {
cardValSetter(keyName);
} else {
const newArr = cardVal;
newArr.pop();
setCardVal(newArr);
}
};
// loop through keyName to display keyboard
for (let i = 0; i < KeyName.length; i++) {
x = i;
if (i < 10) {
rowOne.push(
<Key onPress={() => combiner(KeyName[i])} key={i} index={i} />
);
} else if (i === 10 || i < 19) {
rowTwo.push(
<Key onPress={() => combiner(KeyName[i])} key={i} index={i} />
);
} else {
rowThree.push(
<Key onPress={() => combiner(KeyName[i])} key={i} index={i} />
);
}
}
console.log(keyVal);
console.log(cardVal);
return (
<>
<View style={styles.keyBoard}>
<View style={styles.keyBoardLine}>{rowOne}</View>
<View style={styles.keyBoardLine}>{rowTwo}</View>
<View style={styles.keyBoardLine}>{rowThree}</View>
</View>
</>
);
};
是的,当从状态中删除时,您正在改变它而不是返回一个新数组。
const { cardVal, setCardVal } = useContext(GameContext);
...
const combiner = (keyName) => {
keyValSetter(keyName);
if (keyName !== "Delete") {
cardValSetter(keyName);
} else {
const newArr = cardVal; // <-- reference to state
newArr.pop(); // <-- mutation!!
setCardVal(newArr); // <-- state reference back into state
}
};
cardVal
状态似乎从来都不是更新的数组引用。由于状态引用从未改变,因此 React 假定状态仍然相同并且不会触发重新渲染。
使用功能状态更新从以前的状态正确更新(而不是范围内关闭的任何状态),并将状态浅复制到新的数组引用中。
示例:
const combiner = (keyName) => {
keyValSetter(keyName);
if (keyName !== "Delete") {
cardValSetter(keyName);
} else {
setCardVal(cards => cards.slice(0, -1)) // <-- copy all but last element
}
};
同样,cardValSetter
也应该使用功能状态更新来更新以前的状态。
const cardValSetter = (keyName) => {
setCardVal(cardVal => [...cardVal, keyName]);
};