Ich baue gerade meine erste reaktionsnative Anwendung, die ein einfacher Klon von IMDB ist. Ich verwende NavigatorIOS, um die Statustransaktion zu verwalten und meine Anwendung so modular wie möglich zu erstellen.Invariant Violation: Elementtyp ist ungültig: erwartet einen String, aber erhalten: Objekt. Überprüfen Sie die Rendermethode von 'NavigatorIOS'
Der Fehler tritt auf, wenn ich zu meinem Film Komponente aus meiner Bibliothek Komponente zu gehen versuchen. Die Bibliothek listet alle Filme auf, die der Benutzer gespeichert hat, und die Movie-Komponente nimmt einfach ein Objekt und zeigt die Informationen des übergebenen Films an.
Die besondere daran ist, dass ich meine Film Komponente von meiner Suche Komponente, und ich bin nicht in der Lage wiederverwenden, die Ausnahme zu reproduzieren.
Bibliothek Komponente:
var React = require('react-native');
var Separator = require('../Helpers/Separator');
var Movie = require('../Movie');
var {
Text,
StyleSheet,
View,
ScrollView,
TouchableHighlight,
ActivityIndicatorIOS
} = React;
var styles = StyleSheet.create({
container: {
flex: 1,
},
rowContainer: {
flexDirection: 'column',
flex: 1,
padding: 10
},
name: {
color: '#48BBEC',
fontSize: 18,
paddingBottom: 5
},
year: {
color: '#48BBEC',
fontSize: 14,
paddingBottom: 5
},
description: {
fontSize: 14,
paddingBottom: 5
}
});
class Library extends React.Component{
selectFilm(selectedMovie){
this.props.navigator.push({
title: selectedMovie.Title,
component: Movie,
passProps: { movie: selectedMovie, canSave: false, isAuthenticated: true }
});
}
render(){
var movies = this.props.movies;
var list = movies.map((item, index) => {
return(
<View key={index}>
<View style={styles.rowContainer}>
<TouchableHighlight
onPress={this.selectFilm.bind(this, movies[index])}
underlayColor='transparent'>
<Text style={styles.name}>{movies[index].title}</Text>
</TouchableHighlight>
<Text stlye={styles.year}>{movies[index].year}</Text>
</View>
<Separator />
</View>
)
});
return(
<ScrollView style={styles.container}>
{list}
</ScrollView>
)
}
};
Library.propTypes = {
movies: React.PropTypes.array.isRequired
};
module.exports = Library;
Film Komponente:
var React = require('react-native');
var Badge = require('./Badge.js');
var Library = require('./User/Library.js');
var Separator = require('./Helpers/Separator');
var api = require('../Utils/api');
var {
StyleSheet,
Image,
Text,
View,
ScrollView,
TouchableHighlight,
AsyncStorage
} = React;
var styles = StyleSheet.create({
container: {
flex: 1
},
buttonText: {
fontSize: 18,
color: 'white',
alignSelf: 'center'
},
rowContainer: {
padding: 10
},
rowTitle: {
color: '#48BBEC',
fontSize: 16
},
rowContent: {
fontSize: 19
},
buttonText: {
fontSize: 18,
color: '#111',
alignSelf: 'center'
},
button: {
height: 45,
flexDirection: 'row',
backgroundColor: '#758BF4',
borderColor: 'white',
borderWidth: 1,
borderRadius: 8,
marginBottom: 0,
marginTop: 10,
alignSelf: 'stretch',
justifyContent: 'center'
}
});
class Movie extends React.Component{
componentDidMount() {
AsyncStorage.getItem("token").then((value) => {
this.setState({"token": value});
}).done();
}
getRowTitle(title){
return title[0] ? title[0].toUpperCase() + title.slice(1): title;
}
getTitle(item){
return item[0] ? item[0].toUpperCase() + item.slice(1) : item;
}
handleSubmit(){
api.addMovie(this.state.token, this.props.movie)
.then((res) => {
console.log(res);
if (res === 'Film already exists') {
alert('Film already exists');
} else {
alert('SAVED');
}
});
}
handleDelete(){
api.deleteMovie(this.props.movie.imdbID)
.then((res) => {
this.props.navigator.pop();
});
}
render(){
var showSave;
if (this.props.isAuthenticated) {
showSave = (
this.props.canSave ? <TouchableHighlight style={styles.button} onPress={this.handleSubmit.bind(this)} underlayColor="#48BBEC"><Text style={styles.buttonText}> SAVE </Text></TouchableHighlight> :
<TouchableHighlight style={styles.button} onPress={this.handleDelete.bind(this)} underlayColor="#48BBEC"><Text style={styles.buttonText}>DELETE </Text></TouchableHighlight>
);
}
var movie = this.props.movie;
var topicArr = ['director', 'year', 'rated', 'plot', 'country', 'awards', 'imdbRating'];
var list = topicArr.map((item, index) => {
if (!movie[item]) {
item = this.getTitle(item);
}
return (
<View key={index}>
<View style={styles.rowContainer}>
<Text style={styles.rowTitle}>{this.getRowTitle(item)}</Text>
<Text style={styles.rowContent}> {movie[item]} </Text>
</View>
<Separator />
</View>
)
});
return(
<ScrollView style={styles.container}>
<Badge movie={this.props.movie} />
{list}
{showSave}
</ScrollView>
)
}
};
Movie.propTypes = {
movie: React.PropTypes.object.isRequired
};
module.exports = Movie;
Suchen Komponente:
var React = require('react-native');
var Movie = require('./Movie');
var api = require('../Utils/api');
var {
Text,
View,
TextInput,
TouchableHighlight,
StyleSheet,
ActivityIndicatorIOS,
AsyncStorage
} = React;
var styles = StyleSheet.create({
// Styles
});
class Search extends React.Component{
constructor(props){
super(props);
this.state = {
title: '',
isLoading: false,
token: ''
}
}
componentDidMount() {
AsyncStorage.getItem("token").then((value) => {
this.setState({"token": value});
}).done();
}
handleChange(event){
this.setState({
title: event.nativeEvent.text
});
}
handleSubmit(){
var isAuthenticated = this.state.token !== null ? true : false;
this.setState({
isLoading: true
});
api.findMovie(this.state.title)
.then((res) => {
if (!res.Response) {
this.setState({
error: 'Movie not found',
isLoading: false
});
} else {
this.props.navigator.push({
title: res.Title,
component: Movie,
passProps: {movie: res, canSave: true, isAuthenticated: isAuthenticated}
});
this.setState({
isLoading: false,
error: false,
title: ''
})
}
});
}
render(){
var showErr = (
this.state.error ? <Text>{this.state.error}</Text> : <View></View>
);
return(
<View style={styles.mainContainer}>
<Text style={styles.title}>Search for a movie</Text>
<TextInput
style={styles.searchInput}
value={this.state.title}
onChange={this.handleChange.bind(this)} />
<TouchableHighlight
style={styles.button}
onPress={this.handleSubmit.bind(this)}
underlayColor="white">
<Text style={styles.buttonText}> SEARCH </Text>
</TouchableHighlight>
<ActivityIndicatorIOS
animating={this.state.isLoading}
color= "#111"
size="large">
</ActivityIndicatorIOS>
{showErr}
</View>
)
}
};
module.exports = Search;
Hier ist die Anwendung Fluss meiner App:
Jede Hilfe wäre sehr geschätzt.
da es keinen Fehler gibt, wenn aus der Suche kommt, ich denke, es wäre hilfreich, diese Komponente zu sehen. Im Allgemeinen schlage ich vor, die dynamischen Bits durch hartcodierte Bits zu ersetzen, um das Problem zu isolieren. Eine der Requisiten, die an NavigatotIOS übergeben werden, ist eigentlich ein Objekt statt String –
Danke, ich habe den Code für die Search-Komponente hinzugefügt. Ich habe alle Requisiten fest programmiert und es gibt mir immer noch den gleichen Fehler. – gonzalovazzquez