Реагировать - значение из API не отображается в представлении - PullRequest
0 голосов
/ 16 сентября 2018

Я очень новичок в React Native и прохожу курс, где встречаю эту проблему:

Этот компонент показывает "ТЕКСТ", но не показывает {film.title}

_displayFilm() {
  const { film } = this.state
  if (film != undefined) {
    return (
      <ScrollView style={styles.scrollview_container}>
        <Text>TEXT</Text>
        <Text>{film.title}</Text>
      </ScrollView>
    )
  }
}

Я использую Atom в Ubuntu и использую приложение Expo Android для просмотра результата.

Еще одно неудобство, которое у меня есть, это то, что я не получаю журналы из console.log () в терминале Atom, которые могли бы помочь мне, например, увидеть полный объект фильма json. Значение «title правильное (используйте на другой странице моего приложения).

Если у кого-то есть идея, как ее решить, большое спасибо!

Если полезно, вот полное содержимое файла:

// Components/FilmDetail.js

import React from 'react'
import { StyleSheet, View, Text, ActivityIndicator, ScrollView, Image } from 'react-native'
import { getFilmDetailFromApi, getImageFromApi } from '../API/TMDBApi'
import moment from 'moment'
import numeral from 'numeral'

class FilmDetail extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      film: undefined,
      isLoading: true
    }
  }

  componentDidMount() {
    getFilmDetailFromApi(this.props.navigation.state.params.idFilm).then(data => {
      this.setState({
        film: data,
        isLoading: false
      })
    })
  }

  _displayLoading() {
    if (this.state.isLoading) {
      return (
        <View style={styles.loading_container}>
          <ActivityIndicator size='large' />
        </View>
      )
    }
  }

  _displayFilm() {
    const { film } = this.state
    if (film != undefined) {
      return (
        <ScrollView style={styles.scrollview_container}>
          <Text>TEXT</Text>
          <Text>{film.title}</Text>
          <Text style={styles.title_text}>{film.release_date}</Text>
          <Text style={styles.title_text}>{film.backdrop_path}</Text>
        </ScrollView>
      )
    }
  }

  render() {
    return (
      <View style={styles.main_container}>
        {this._displayLoading()}
        {this._displayFilm()}
      </View>
    )
  }
}

const styles = StyleSheet.create({
  main_container: {
    flex: 1
  },
  loading_container: {
    position: 'absolute',
    left: 0,
    right: 0,
    top: 0,
    bottom: 0,
    alignItems: 'center',
    justifyContent: 'center'
  },
  scrollview_container: {
    flex: 1
  },
  image: {
    height: 169,
    margin: 5
  },
  title_text: {
    fontWeight: 'bold',
    fontSize: 35,
    flex: 1,
    flexWrap: 'wrap',
    marginLeft: 5,
    marginRight: 5,
    marginTop: 10,
    marginBottom: 10,
    color: '#000000',
    textAlign: 'center'
  },
  description_text: {
    fontStyle: 'italic',
    color: '#666666',
    margin: 5,
    marginBottom: 15
  },
  default_text: {
    marginLeft: 5,
    marginRight: 5,
    marginTop: 5,
  }
})

export default FilmDetail

И вызываемый API здесь:

const API_TOKEN = "MY_API_TOKEN"

export function getFilmsFromApiWithSearchedText (text, page) {
  const url = 'https://api.themoviedb.org/3/search/movie?api_key=' + API_TOKEN + '&language=fr&query=' + text + "&page=" + page
  return fetch(url)
    .then((response) => response.json())
    .catch((error) => console.error(error))
}

export function getImageFromApi(name) {
  return 'https://image.tmdb.org/t/p/w185' + name
}

export function getFilmDetailFromApi(id) {
  const url = 'https://api.themoviedb.org/3/movie/' + id + 'api_key=' + API_TOKEN + '&language=fr'
  return fetch(url)
    .then((response) => response.json())
    .catch((error) => console.log(error))
}

Ответы [ 2 ]

0 голосов
/ 16 сентября 2018

Я считаю, что ваша функция должна быть примерно такой:

export function getFilmDetailFromApi(id) {
    const url = 'https://api.themoviedb.org/3/movie/' + id + '?api_key=' + API_TOKEN + '&language=fr'
  return fetch(url)
    .then((response) => response.json())
    .then((responseJson) => {
        return responseJson;
    })
    .catch((error) => console.log(error))
}

Попробуйте это в вашем компоненте:

this.state = {
    film: {}, //change the undefined
    isLoading: true
}

componentDidMount() {
    this.getMovie();
}


getMovie() {
    const movie = getFilmDetailFromApi(this.props.navigation.state.params.idFilm);
    if (movie.hasOwnProperty('id')) { //that means a movie was returned
        this.setState({ film: movie, isLoading: false });
    }
}

Текст в _displayFilm показывается, потому что вы уже установили фильм как неопределенный. Так что, пока состояние не изменится, текст будет отображаться. Измените _displayFilm:

_displayFilm() {
    const { film } = this.state
    if (film.hasOwnProperty('id')) {
        return (
            <ScrollView style={styles.scrollview_container}>
                <Text>TEXT</Text>
                <Text>{film.title}</Text>
                <Text style={styles.title_text}>{film.release_date}</Text>
                <Text style={styles.title_text}>{film.backdrop_path}</Text>
            </ScrollView>
        )
    }
}

Теперь проблема может заключаться в том, что вы не получаете правильные данные. Возможно, ваши данные содержатся в response.data.data или response.data, а не только в response. Так что непременно console.log(response) и осмотрите

0 голосов
/ 16 сентября 2018

Я думаю, что вы пропускаете ? до api_key:

const url = 'https://api.themoviedb.org/3/movie/' + id + '?api_key=' + API_TOKEN + '&language=fr'

, вам нужно починить консоль, так как она должна показывать, что ответ в атм консоли неверен... HTH

...