javascript - TypeError:未定义不是对象(评估'_this.props.navigation.navigate')reactNavigation 5
问题描述
我正在尝试从我的 search.js 文件中更改视图。但我不能,而且我在崩溃的应用程序中遇到了这个错误。每次我在我的 search.js 文件中执行 console.log(this.props) 时,我都会得到这个结果: ------------------------- ------------opooi- 对象 {} 。
这是我的 Search.js 文件
//Components/Search.js
import React from 'react'
import { StyleSheet, View, TextInput, Button, Text, FlatList, ActivityIndicator } from 'react-native'
import FilmItem from './FilmItems'
import { getFilmsFromApiWithSearchedText } from '../API/TMDBApi'
class Search extends React.Component {
_displayDetailForFilm = (idFilm) => {
//console.log("Display film with id " + idFilm + this )
console.log('----------------------opooi-')
console.log(this.props)
// Cette commande ci-dessous est non fonctionnel donc si vous avez la solution...
this.props.navigation.navigate("Details")
}
constructor(props) {
super(props)
this.page = 0
this.totalPages = 0
this.searchedText = "" // Initialisation de notre donnée searchedText en dehors du state
this.state = {
films: [],
isLoading : false // Affiche temoin de chargement desactiver de base
}
}
_loadFilms() {
this.setState({ isLoading: true})
if (this.searchedText.length > 0) { // Seulement si le texte recherché n'est pas vide
getFilmsFromApiWithSearchedText(this.searchedText, this.page+1).then(data => {
this.page = data.page
this.totalPages = data.total_pages
this.setState({
films: [...this.state.films , ...data.results ],
isLoading : false
})
})
}
}
_displayLoading() {
if (this.state.isLoading) {
return (
<View style={styles.loading_container}>
<ActivityIndicator size='large' />
{/* Le component ActivityIndicator possède une propriété size pour définir la taille du visuel de chargement : small ou large. Par défaut size vaut small, on met donc large pour que le chargement soit bien visible */}
</View>
)
}
}
_searchFilms() {
this.page = 0
this.totalPages = 0
this.setState({
films: []
}, ()=> {
// J'utilise la paramètre length sur mon tableau de films pour vérifier qu'il y a bien 0 film
console.log("Page : " + this.page + " / TotalPages : " + this.totalPages + " / Nombre de films : " + this.state.films.length)
this._loadFilms()
})
}
_searchTextInputChanged(text) {
this.searchedText = text // Modification du texte recherché à chaque saisie de texte, sans passer par le setState comme avant
}
render() {
const { film, displayDetailForFilm } = this.props
console.log('----------------------------')
console.log(this.props);
// test si lóbject this.props est null..
return (
<View
style={styles.main_container}
onPress={() => displayDetailForFilm(film.id)}
>
<TextInput
style={styles.textinput}
placeholder='Titre du film'
onChangeText={(text) => this._searchTextInputChanged(text)}
onSubmitEditing={() => this._searchFilms()}
/>
<Button title='Rechercher' onPress={() => this._searchFilms()}/>
<FlatList
data={this.state.films}
keyExtractor={(item) => item.id.toString()}
onEndReachedThreshold={0.5}
onEndReached={() => {
if (this.page < this.totalPages) {
this._loadFilms()
}
}}
这是我的 Navigation.js 文件
// Navigation/Navigation.js
import * as React from 'react';
import Search from '../Components/Search';
import FilmDetail from '../Components/FilmDetail';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
const Stack = createStackNavigator();
const HomeScreen =({ navigation }) => {
return (
<Search/>
);
}
const DetailsScreen = ({ navigation }) => {
return (
<FilmDetail/>
);
}
function Navigation() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} options={{ title: 'Home' }} />
<Stack.Screen name="Details" component={DetailsScreen} options={{ title: 'Details' }} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default Navigation;
这是我使用 TouchableOpacity 的 Filmitem.js 文件
// Components/FilmItem.js
import React from 'react'
import { StyleSheet, View, Text, Image, TouchableOpacity } from 'react-native'
import { getImageFromApi } from '../API/TMDBApi'
class FilmItem extends React.Component {
render() {
const film = this.props.film
const displayDetailForFilm = this.props.displayDetailForFilm
return (
<TouchableOpacity
style={styles.main_container}
onPress={() => displayDetailForFilm(film.id)}>
<Image
style={styles.image}
source={{uri: getImageFromApi(film.poster_path)}}
/>
<View style={styles.content_container}>
<View style={styles.header_container}>
<Text style={styles.title_text}>{film.title}</Text>
<Text style={styles.vote_text}>{film.vote_average}</Text>
</View>
<View style={styles.description_container}>
<Text style={styles.description_text} numberOfLines={6}>{film.overview}</Text>
{/* La propriété numberOfLines permet de couper un texte si celui-ci est trop long, il suffit de définir un nombre maximum de ligne */}
</View>
<View style={styles.date_container}>
<Text style={styles.date_text}>{film.release_date}</Text>
</View>
</View>
</TouchableOpacity>
)
}
}
const styles = StyleSheet.create({
main_container: {
height: 190,
flexDirection: 'row'
},
image: {
width: 120,
height: 180,
margin: 5,
backgroundColor: 'gray'
},
content_container: {
flex: 1,
margin: 5
},
header_container: {
flex: 3,
flexDirection: 'row'
},
title_text: {
fontWeight: 'bold',
fontSize: 20,
flex: 1,
flexWrap: 'wrap',
paddingRight: 5,
color: '#FFFFFF'
},
vote_text: {
fontWeight: 'bold',
fontSize: 26,
color: '#FFFFFF'
},
description_container: {
flex: 7
},
description_text: {
fontStyle: 'italic',
color: '#FFFFFF'
},
date_container: {
flex: 1
},
date_text: {
textAlign: 'right',
fontSize: 14,
color: '#FFFFFF'
}
})
export default FilmItem
这是我试图访问的视图
// Components/FilmDetail.js
import React from 'react'
import { StyleSheet, View, Text } from 'react-native'
class FilmDetail extends React.Component {
render() {
return (
<View style={styles.main_container}>
<Text>Détail du film</Text>
<Button
title={`Go to ${Home}`}
onPress={() => navigation.navigate(Home)}
/>
</View>
)
}
}
const styles = StyleSheet.create({
main_container: {
flex: 1,
}
})
export default FilmDetail
解决方案
错误告诉你你需要知道什么
未定义不是对象(评估'_this.props.navigation.navigate')
它指的是这条线。
this.props.navigation.navigate("Details")
显然this.props
是一个对象,但this.props.navigation
不是,所以this.props.navigation.navigate
将无法评估。原因是 因为您没有将道具传递this.props.navigation
给组件。undefined
navigation
const HomeScreen =({ navigation }) => {
return (
<Search/>
);
}
在这里,您定义了一个正在接收道具的HomeScreen
组件,但您得到的错误是在您的组件中没有该道具。您可以简单地将其传入:navigation
Search
const HomeScreen =({ navigation }) => {
return (
<Search navigation={navigation}/>
);
}
...或者如果您的组件真的那么简单,您可以这样做:
const HomeScreen = Search;
...并让道具直接Stack.Navigator
传递到您的组件中。navigation
Search
推荐阅读
- node.js - 如何使不和谐机器人发出-100到100之间的随机数
- angular - Kendo 表单控件适用于一个组件但不适用于其他组件
- java - 我试图找出一个数字是否是素数,并且错误抛出“参数类型 int int 的运算符 && 未定义”
- jakarta-ee - 应用服务器是否能够优化 CDI 实例的范围,还是我们应该自己定义 CDI 范围
- python - 如何在python中找到多个不重复的数字?
- c - 如何使用 for 循环而不是 printf 语句来执行枚举列表,如下代码所示?
- android - SMB/CIFS URL 在 Android 浏览器中不起作用。如何在 Android 浏览器中打开 SMB 共享文件和文件夹
- powershell - 如何通过 Powershell 修改文件属性中的“媒体创建”字段
- flutter - Flutter web,onTap 在 safari 上被调用两次
- phpmyadmin - PhpMyadmin 如何逐块导入数据库(按表组)