javascript - React Native(Expo):TouchableOpacity onPress 不是函数/未定义
问题描述
我正在关注关于 Linkedin-Learning 的本教程,突然间我的代码不再工作了。不幸的是,我并不真正理解这些错误消息:
此警告始终出现:
警告:失败的道具类型:道具
onPress
在 中标记为必填RandomNumber
,但其值为undefined
。
如果我按下其中一个“按钮”,则会出现以下错误消息:
TypeError:_this.props.onPress 不是函数。(在 '_this.props.onPress(_this.props.id)' 中,'_this.props.onPress' 未定义)
随机数.js:
import React from "react";
import { Text, TouchableOpacity, StyleSheet } from "react-native";
import PropTypes from "prop-types";
class RandomNumber extends React.Component {
static propTypes = {
id: PropTypes.number.isRequired,
number: PropTypes.number.isRequired,
isDisabled: PropTypes.bool.isRequired,
onPress: PropTypes.func.isRequired,
};
handlePress = () => {
if (this.props.isDisabled) {
return;
}
this.props.onPress(this.props.id);
};
render() {
return (
<TouchableOpacity onPress={this.handlePress}>
<Text style={[styles.random, this.props.isDisabled && styles.disabled]}>
{this.props.number}
</Text>
</TouchableOpacity>
);
}
}
const styles = StyleSheet.create({
random: {
backgroundColor: "#999",
width: 120,
marginHorizontal: 15,
marginVertical: 25,
fontSize: 35,
textAlign: "center",
},
disabled: {
opacity: 0.2,
},
});
export default RandomNumber;
游戏.js:
import React from "react";
import { View, Text, Button, StyleSheet } from "react-native";
import PropTypes from "prop-types";
import RandomNumber from "./RandomNumber";
import shuffle from "lodash.shuffle";
class Game extends React.Component {
static propTypes = {
randomNumberCount: PropTypes.number.isRequired,
initialSeconds: PropTypes.number.isRequired,
onPlayAgain: PropTypes.func.isRequired,
};
state = { selectedIds: [], remainingSeconds: this.props.initialSeconds };
gameStatus = "PLAYING";
randomNumbers = Array.from({ length: this.props.randomNumberCount }).map(
() => 1 + Math.floor(10 * Math.random())
);
target = this.randomNumbers
.slice(0, this.props.randomNumberCount - 2)
.reduce((acc, curr) => acc + curr, 0);
shuffledRandomNumbers = shuffle(this.randomNumbers);
componentDidMount() {
this.intervalID = setInterval(() => {
this.setState(
(prevState) => {
return { remainingSeconds: prevState.remainingSeconds - 1 };
},
() => {
if (this.state.remainingSeconds === 0) {
clearInterval(this.intervalID);
}
}
);
}, 1000);
}
componentWillUnmount() {
clearInterval(this.intervalID);
}
isNumberSelected = (numberIndex) => {
return this.state.selectedIds.indexOf(numberIndex) >= 0;
};
selectNumber = (numberIndex) => {
this.setState((prevState) => ({
selectedIds: [...prevState.selectedIds, numberIndex],
}));
};
UNSAFE_componentWillUpdate(nextProps, nextState) {
if (
nextState.selectedIds !== this.state.selectedIds ||
nextState.remainingSeconds === 0
) {
this.gameStatus = this.calcGameStatus(nextState);
if (this.gameStatus !== "PLAYING") {
clearInterval(this.intervalID);
}
}
}
calcGameStatus = (nextState) => {
const sumSelected = nextState.selectedIds.reduce((acc, curr) => {
return acc + this.shuffledRandomNumbers[curr];
}, 0);
if (this.state.remainingSeconds === 0) {
return "LOST";
}
if (sumSelected < this.target) {
return "PLAYING";
}
if (sumSelected === this.target) {
return "WON";
}
if (sumSelected > this.target) {
return "LOST";
}
};
render() {
const gameStatus = this.gameStatus;
return (
<View style={styles.container}>
<Text style={[styles.target, styles[`STATUS_${gameStatus}`]]}>
{this.target}
</Text>
<View style={styles.randomContainer}>
{this.shuffledRandomNumbers.map((randomNumber, index) => (
<RandomNumber
key={index}
id={index}
number={randomNumber}
onPress={this.state.selectNumber}
isDisabled={
this.isNumberSelected(index) || gameStatus !== "PLAYING"
}
/>
))}
</View>
{this.gameStatus !== "PLAYING" && (
<Button title="Play Again" onPress={this.props.onPlayAgain} />
)}
<Text>{this.state.remainingSeconds}</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: "#ddd",
flex: 1,
},
target: {
fontSize: 40,
backgroundColor: "#bbb",
margin: 50,
textAlign: "center",
},
randomContainer: {
flex: 1,
flexDirection: "row",
flexWrap: "wrap",
justifyContent: "space-around",
},
STATUS_PLAYING: {
backgroundColor: "#bbb",
},
STATUS_WON: {
backgroundColor: "green",
},
STATUS_LOST: {
backgroundColor: "red",
},
});
export default Game;
应用程序.js:
import React from "react";
import Game from "./Game";
class App extends React.Component {
state = { gameId: 1 };
resetGame = () => {
this.setState((prevState) => {
return { gameId: prevState.gameId + 1 };
});
};
render() {
return (
<Game
key={this.state.gameId}
onPlayAgain={this.resetGame}
randomNumberCount={6}
initialSeconds={10}
/>
);
}
}
export default App;
我已经尝试过其他帖子的一些解决方案,但没有一个有效。
任何帮助表示赞赏。
解决方案
推荐阅读
- python - 如何在 PyQt5 builder 中使用来自网络的图像
- swift - 递归发送值到 combineLatest 发布者
- javascript - 'ESLINT_NO_DEV_ERRORS' 不是内部或外部命令、可运行程序或批处理文件
- php - Flutter Web:我在 API 调用中收到 XMLHttpRequest 错误
- javascript - 如何使用适用于 JavaScript 的 AWS 开发工具包 V3 版本将 PDF 文件的 ReadableStream 存储到磁盘
- html - 使 div 粘在另一个 div 的底部
- hash - (新手) Valgrind 关于哈希表创建的内存泄漏
- c# - 将大数据集上传到tarantool的最佳方法是什么
- r - 如何在单个列中对行进行分组
- pytest - 使用 pytest-bdd 进行乘法输入测试