簡體   English   中英

undefined 不是 React Native 中的 object(評估“item.Title”)

[英]undefined is not an object (evaluating 'item.Title') in React Native

所以我正在制作這個電影瀏覽器項目,我必須從 OMDb API( http://www.omdbapi.com/ )獲取數據並在 Flatlist 組件中顯示數據。

雖然我設法顯示搜索的每部電影的 10 個結果(因為 API 在每次調用時返回 10 個項目),但我添加了一個按鈕,該按鈕將運行 function 以再次向 ZDB974238714CA8DE634A7F14Z 發送請求,並使用參數 fetch3104ZA7F 獲取更多結果將結果連接到電影。

但是,只要我按下按鈕並運行 function,就會出現這個錯誤undefined is not an object (evaluating 'item.Title')

這是我的 Home 組件代碼 => Home.js

import React, { useState, useEffect } from 'react';
import { StyleSheet, View, Text, FlatList, TouchableHighlight, Image, Button} from 'react-native';
import { TextInput } from 'react-native-gesture-handler';
import { fetchMovies } from "../api/api";




export default class Home extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            text: "",
            movies: null,
        };
    }
      //update search text
    componentDidUpdate(prevState) {
        if (this.state.text !== prevState.text) {
            this.getSearch(this.state.text);            
        }
    }
      //get search results from fetchMovies
    getSearch = async text => {
        const results = await fetchMovies(text)
        this.setState({ movies: results });
    };


    ////////////////////////////Function making API call using the page parameter///////////
    //loading more movies
    handleLoadMore = async() => {
        try {
            const page = Math.trunc(this.state.movies.length / 10) + 1;
            const res = await fetchMovies(this.state.text, page);
            this.setState(prevState => ({
                movies: prevState.movies.concat(res.movies)
            })) 
        }catch(err){
            console.log(err.message);
        }
    }
    //////////////////////////////////////////////////////////


      //movie title and poster to render in the flatlist
    movieCard = ({ item }) => {
        return (
        <TouchableHighlight
            style={styles.movieCard}
            underlayColor="white"
            onPress={() => {
            this.props.navigation.navigate("Details", {
                    title: item.title,
                    id: item.imdbID
                });
            }}
        >

            <View>
                <Image
                        style={styles.movieImage}
                        source={ {uri: item.Poster} }                 
                    />
                <View style={{alignItems: 'center'}}>
                    <Text style={styles.movieTitle}>{item.Title} ({item.Year})</Text>
                </View>
            </View>
        </TouchableHighlight>
        );
    };



render() {
    return(
        <View style={styles.container}>
            <TextInput 
                style={styles.searchBox}
                autoCorrect={false}
                autoCapitalize='none'
                autoFocus maxLength={45}
                placeholder='Search'
                onChangeText={(text) => this.setState({ text })}
                value={this.state.text}
            />

            {this.state.movies ?
            <FlatList
                style={styles.movieList}
                data={this.state.movies}
                renderItem={this.movieCard}
                keyExtractor={item => item.Title + item.imdbID}

            />
            :
            <Text
                style={{ 
                    alignSelf: 'center', 
                    paddingTop: 150, 
                    justifyContent: 'center', 
                    color: '#8a8787', 
                    fontStyle: 'italic' }}>
                search for a movie above...
            </Text>
            }

            <Button
                onPress={this.handleLoadMore}
                title="Load More"
                color="#841584"
            />
        </View>
    )
}
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        padding: 20,
        backgroundColor: '#DDD',
        alignItems: 'center',
    },
    searchBox: {
        fontSize: 20,
        fontWeight: '300',
        padding: 10,
        width: '100%',
        backgroundColor: 'white',
        borderRadius: 10,
        marginBottom: 30
    },
    movieList: {
        flex: 1, 
        marginHorizontal: 30,
    },
    movieCard: {
        flex: 1,
        margin: 5,
        padding: 5,
    },
    movieImage: {
        width: '100%',
        height: 350,
        borderRadius: 10,
        alignSelf: 'center',
    },
    movieTitle: {
        marginTop: 10,
        fontSize: 20,
        color: '#333'
    }
});

這是 api 函數的代碼 => api.js


const API_KEY = "API_KEY";


//fetch search data from omdb api
export const fetchMovies = async (response, page) => {
  const url = `http://www.omdbapi.com/?apikey=${API_KEY}&s=${response}`;
  try {
    let response = await fetch(url);
    if(page) {
      response = await fetch(url + `&page=${page}`)
    }
    const { Search } = await response.json();
    return Search;
  } catch (err) {
    return console.log(err);
  }
};

//fetch ID from omdb api
export const fetchById = async id => {
  const url = `http://www.omdbapi.com/?apikey=${API_KEY}&i=${id}`;
  try {
    const response = await fetch(url);
    const results = await response.json();
    return results;
  } catch (err) {
    return console.log(err);
  }
};

我知道解決這個問題可能很簡單,但是對於 react-native 來說是新手,我無法弄清楚。

關於FlatList ,在文檔中,他們顯然通過 lambda 將渲染項目返回給renderItem道具

另外你初始化的state.movies是 null 我認為它應該是一個空數組

 this.state = {
   text: "",
   movies: [],
 };

 <FlatList
  style={styles.movieList}
  data={this.state.movies}
  renderItem={({item}) => this.movieCard({item})}
  keyExtractor={item => item.Title + item.imdbID}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM