【发布时间】:2021-10-25 03:34:06
【问题描述】:
我遇到以下错误“错误:元素类型无效:需要字符串(对于内置组件)或类/函数(对于复合组件),但得到:未定义。您可能忘记导出组件从它定义的文件中,或者您可能混淆了默认和命名导入。
检查TitleScreen的渲染方法。"
这里显示了导入/导出:
TitleScreen.js
import React, { Component } from 'react';
import { StyleSheet, ImageBackground, View, Text, TouchableOpacity } from 'react-native';
import { AdMobBanner } from 'expo';
import { Dimensions } from 'react-native';
const screenX = Dimensions.get('window').width;
const screenY = Dimensions.get('window').height;
export default class TitleScreen extends Component {
render() {
return(
<ImageBackground
source={require('../assets/space_background.png')}
style={{width: screenX, height: screenY}}
>
<View style={styles.isJustGameContainer}>
<Text style={styles.isJustGameText}>Is Just Game</Text>
</View>
<View style={styles.titleContainer}>
<Text style={styles.title}>Space Shooter</Text>
</View>
<View style={styles.playerStats}>
<Text style={styles.playerStatText}>
High Score: {this.props.highScore}
</Text>
<Text style={styles.playerStatText}>
Enemies Destroyed: {this.props.allEnemiesDestroyed}
</Text>
<Text style={styles.playerStatText}>
Coins Collected: {this.props.allCoinsCollected}
</Text>
</View>
<View style={styles.titleScreenContainer}>
<ImageBackground
source={require('../assets/player_large.png')}
style={styles.titleImage}
>
</ImageBackground>
<TouchableOpacity
style={styles.buttonContainer}
onPress={() => {
this.props.playMenuNavigation();
this.props.startGame()
}}
>
<Text style={styles.buttonText}>
Start Game
</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.buttonContainer}
onPress={() => {
this.props.playMenuNavigation();
this.props.openControls();
}}
>
<Text style={styles.buttonText}>
Controls
</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.buttonContainer}
onPress={() => {
this.props.playMenuNavigation();
this.props.openInfo()
}}
>
<Text>
About
</Text>
</TouchableOpacity>
</View>
<View style={styles.adMobBanner}>
<AdMobBanner
bannerSize="fullBanner"
adUnitID="ca-app-pub-5830175342552944/8024421682"
testDeviceID="EMULATOR"
/>
</View>
</ImageBackground>
)
}
}
App.js
import { StyleSheet, Text, View, StatusBar, ImageBackground, AsyncStorage } from 'react-native';
import Expo from 'expo';
import { Audio } from 'expo-av';
import Player from './components/Player.js';
import { Dimensions } from 'react-native';
import { GameEngine } from 'react-native-game-engine';
import GameLogic from './GameLogic.js';
import TitleScreen from './views/TitleScreen';
import Info from './views/Info.js';
import Controls from './views/Controls.js';
import EndGameScreen from './views/EndGameScreen.js';
import Config from './config/Config.js';
import EntitySizes from './config/EntitySizes.js';
export default class App extends PureComponent {
constructor(props) {
super(props);
this.screenX = Dimensions.get('window').width;
this.screenY = Dimensions.get('window').height;
this.playerWidth = 50;
this.menuNavigation = new Audio.Sound();
this.menuNavigation.loadAsync(require('./assets/sound_bits/menu_navigation.mp3'));
this.state = {
// Current Game Stats
points: 0,
coinsCollected: 0,
shotsFired: 0,
enemiesDestroyed: 0,
playerHealth: Config.gameDefaults.playerHealth,
// Player Stats
highScore: 0,
allEnemiesDestroyed: 0,
allCoinsCollected: 0,
shotsLeft: Config.gameDefaults.shotsLeft,
hasGameStarted: false,
hasGameEnded: false,
isInfoOpen: false,
isControlsOpen: false,
causeOfEnd: '',
};
}
componentDidMount = () => {
this.GameLogic = new GameLogic(this.setState.bind(this));
this.readerPlayerStats();
}
readerPlayerStats = () => {
AsyncStorage.multiGet(['highScore', 'allEnemiesDestroyed', 'allCoinsCollected']).then(res => {
let tempHighScore = 0;
let tempAllEnemiesDestroyed = 0;
let tempAllCoinsCollected = 0;
// highScore
if (res[0][1] !== null) {
tempHighScore = String(res[0][1]);
}
// tempAllEnemiesDestroyed
if (res[1][1] !== null) {
tempAllEnemiesDestroyed = String(res[1][1]);
}
// tempAllCoinsCollected
if (res[2][1] !== null) {
tempAllCoinsCollected = String(res[2][1]);
}
this.setState({
highScore: tempHighScore,
allEnemiesDestroyed: tempAllEnemiesDestroyed,
allCoinsCollected: tempAllCoinsCollected,
})
});
}
backToTitleScreen = () => {
this.GameLogic.resetGame();
this.setState({
hasGameStarted: false,
hasGameEnded: false,
isInfoOpen: false,
isControlsOpen: false,
points: 0,
coinsCollected: 0,
shotsLeft: Config.gameDefaults.shotsLeft,
playerHealth: Config.gameDefaults.playerHealth,
});
}
render() {
if (this.state.hasGameStarted)
{
return (
<ImageBackground
source={require('./assets/space_background.png')}
style={{width: this.screenX, height: this.screenY}}
>
<GameEngine
style={styles.gameContainer}
systems={[
this.GameLogic.gameLoop,
this.GameLogic.movePlayer,
this.GameLogic.fireProjectile,
this.GameLogic.chanceToSpawnEnemy,
this.GameLogic.chanceToSpawnFallingCollectible,
this.GameLogic.chanceToSpawnFallingHeart,
this.GameLogic.chanceToSpawnAsteroid,
this.GameLogic.playAgain,
]}
entities={{
1: {
name: 'Player',
size: EntitySizes.PLAYER_SIZE,
circle: EntitySizes.PLAYER_CIRCLE,
health: this.state.playerHealth,
position: [this.screenX / 2 - this.playerWidth / 2, this.screenY - 100],
renderer: <Player/>
},
// @Dev to set static object, make sure entity doesn't have name an is in the visible field
// 2: {
// position: [this.screenX / 3 - this.playerWidth / 2, this.screenY - 100],
// renderer: <Projectile/>
// }
}}
>
<StatusBar hidden={true}/>
<EndGameScreen
playMenuNavigation={() => this.menuNavigation.replayAsync()}
points={this.state.points}
shotsFired={this.state.shotsFired}
enemiesDestroyed={this.state.enemiesDestroyed}
hasGameEnded={this.state.hasGameEnded} //@TODO this.state.hasGameEnded
playAgain={(value) => this.GameLogic.setPlayAgain(value)}
backToTitleScreen={() => this.backToTitleScreen()}
/>
</GameEngine>
</ImageBackground>
);
}
else if (!this.state.hasGameStarted && !this.state.isInfoOpen && !this.state.isControlsOpen) {
return (
<View>
<StatusBar hidden={true}/>
<TitleScreen
playMenuNavigation={() => this.menuNavigation.replayAsync()}
startGame={() => this.setState({hasGameStarted: true})}
openControls={() => this.setState({isControlsOpen: true})}
openInfo={() => this.setState({isInfoOpen: true})}
allCoinsCollected={this.state.allCoinsCollected}
allEnemiesDestroyed={this.state.allEnemiesDestroyed}
highScore={this.state.highScore}
/>
</View>
);
}
else if (!this.state.hasGameStarted && this.state.isInfoOpen) {
return (
<View>
<StatusBar hidden={true}/>
<Info
closeInfo={() => this.setState({isInfoOpen: false})}
playMenuNavigation={() => this.menuNavigation.replayAsync()}
/>
</View>
)
}
else if (!this.state.hasGameStarted && this.state.isControlsOpen) {
return(
<View>
<StatusBar hidden={true}/>
<Controls
closeControls={() => this.setState({isControlsOpen: false})}
playMenuNavigation={() => this.menuNavigation.replayAsync()}
/>
</View>
)
}
}
}
我尝试使用 import TitleScreen from './views/TitleScreen.js'; 更改 App.js 中的导入,但它引发了同样的错误。
【问题讨论】:
-
不,不一样。就我而言,我没有使用任何选择标签或 type =“select”。所以我不知道为什么它会抛出错误。
标签: reactjs react-native