简体   繁体   中英

How to render the response API with Flatlist in react native?

I have some issue with a Flatlist, I need to render the response data from API in a Flatlist but it doesn't work! but when I set the static data it works fine! and when i logging the { item } i don't show anything in Debugging! i think the syntax of Flatlist it's right! anybody, can you help me with this issue?

mycode here

import React, { Component } from "react";
import {
  StyleSheet,
  Text,
  View,
  TextInput,
  ScrollView,
  Image,
  ActivityIndicator,
  FlatList,
  ListItem
} from "react-native";
import Moment from "react-moment";

import Icon from "react-native-vector-icons/dist/FontAwesome";

export default class App extends Component {
  constructor(props) {
    super(props);
    this.ApiKeyRef = "****";

    this.watchPositionOpts = {
      enableHighAccuracy: true,
      timeout: 20000,
      maximumAge: 1000,
      distanceFilter: 5
    };
    this.state = {
      isLoading: true,
      dataSource: [],
      latitude: null,
      longitude: null,
      error: null

    };
  }

  componentDidMount() {
    this.watchId = navigator.geolocation.watchPosition(
      this.watchPositionSuccess,
      this.watchPositionFail,
      this.watchPositionOpts
    );
  }

  componentWillUnmount() {

    navigator.geolocation.clearWatch(this.watchId);
    navigator.geolocation.stopObserving();
  }

  watchPositionSuccess = position => {
    this.setState(
      {
        latitude: position.coords.latitude,
        longitude: position.coords.longitude,
        error: null
      },
      () => this.fetchCallback()
    );
  };

  watchPositionFail = err => {
    this.setState({ error: err.message });
  };

  fetchCallback = async () => {
    const { latitude, longitude } = this.state;
    const req = `http://api.openweathermap.org/data/2.5/forecast?lat=${latitude}&lon=${longitude}&units=metric&appid=${
      this.ApiKeyRef
    }`;
    const callback = responseJson => {
      // console.log(responseJson);
      // console.log(responseJson.city.name);
    };

    await fetch(req)
      .then(response => response.json())
      .then(responseJson =>
        this.setState({ isLoading: false, dataSource: responseJson }, () =>
          callback(responseJson)
        )
      )
      .catch(error => console.log(error));
  };

  render() {
    const { dataSource } = this.state;

    if (this.state.isLoading) {
      return (
        <View style={{ flex: 1, padding: 20 }}>
          <ActivityIndicator />
        </View>
      );
    }

    const icon =
      dataSource.list[0].main.temp <= 20
        ? require("./assets/cloudySun.png")
        : require("./assets/sunny.png");

    return (
      <ScrollView style={styles.container}>
        <View style={styles.head}>
          <Text style={styles.titleApp}>Weather App</Text>

        </View>

        <View style={styles.searchSection}>
          <Icon
            style={styles.searchIcon}
            name="search"
            size={15}
            color="#333"
          />

          <TextInput
            style={styles.input}
            placeholder="Find Your City.."
            underlineColorAndroid="transparent"
          />
        </View>

        <View style={styles.details}>

{console.log(this.state.dataSource.city.name)} // I get the City name 
          <FlatList
            data={this.state.dataSource}
            renderItem={({ item }) => (
              <Text>
                {item.message}, {item.city.name}
    {console.log(item)} // NO Output
              </Text>
            )}
            keyExtractor={(item, index) => index}
          />

        </View>
      </ScrollView>
    );
  }
}

Add extraData props to FlatList. extraData is used for re-render the FlatList. extraData

Maybe it will help you.

           <FlatList
                data={dataSource}
                extraData={this.state} //for re-render the Flatlist data item
                renderItem={({ item }) => (
                  <Text>
                    {item.message}, {item.city.name}
                  </Text>
                )}
                keyExtractor={(item, index) => index}
              />

convert object response to the array

      await fetch(req)
          .then(response => response.json())
          .then(responseJson =>{
            let data = [];
            data.push(responseJson); //convert object response to array
            this.setState({ isLoading: false, dataSource: data }, () =>
              callback(data)
            )}
          )
          .catch(error => console.log(error));

you also have to change your logic for icons in render method:

const icon =
      dataSource[0].list[0].main.temp <= 20
        ? require("./assets/cloudySun.png")
        : require("./assets/sunny.png");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM