javascriptreactjsreact-native

I am trying to run this react native screen where it fetches data for me. This gets run when i click the text from a home screen. But it's not working


This is where my home screen is:

import React, { useState } from "react";
import {
  StyleSheet,
  View,
  Text,
  Button,
  FlatList,
  TouchableOpacity,
} from "react-native";
import { globalStyles } from "../styles/global";
import Card from "../shared/card";
import FlatButton from "../shared/button";
import { TextInput } from "react-native-gesture-handler";
import { AntDesign } from "@expo/vector-icons";
import Weather from "./weather";

export default function Home({ navigation }) {
  //add state here
  const [reviews, setReviews] = useState([
    { title: "Let's Snowboard", rating: 4, body: "blue", key: 1 },
  ]);
  const [city, setCity] = useState("");

  return (
    <View style={globalStyles.container}>
      <View style={styles.searchBox}>
        <TextInput
          placeholder="search"
          placeholderTextColor="lightcoral"
          style={styles.searchText}
          onChange={(text) => setCity(text)}
        />
        <TouchableOpacity style={styles.buttonTouch} onPress={Weather}>
          <AntDesign name="search1" size={28} color="lightcoral" />
        </TouchableOpacity>
      </View>
      <FlatList
        data={reviews}
        renderItem={({ item }) => (
          <TouchableOpacity
            onPress={() => navigation.navigate("Weather", item)}
          >
            <Card>
              <Text style={globalStyles.titleText}>{item.title}</Text>
            </Card>
          </TouchableOpacity>
        )}
      />
      <FlatButton text="Let's snowboard?" />
    </View>
  );
}

For my weather screen:

import React, { useState } from "react";
import { StyleSheet, Text, View, Image } from "react-native";
import { globalStyles } from "../styles/global";

const Weather = () => {
  const [date, setData] = useState([]);
  const [icon, setIcon] = useState("");
  const [cityDisplay, setCityDisplay] = useState("");
  const [desc, setDesc] = useState("");
  const [main, setMain] = useState("");
  const [humidity, setHumidity] = useState("");
  const [pressure, setPressure] = useState("");
  const [visibility, setVisibility] = useState("");
  const [temp, setTemp] = useState("");

  async function fetchWeather() {
    try {
      const response = await fetch(
        "https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=***"
      );
      const json = await response.json();
      setData({ data: json });
      setTemp({ temp: (json.main.temp - 273.15).toFixed(2) + " C" });
      setCityDisplay({ cityDisplay: json.name });
      setIcon({ icon: json.weather[0].icon });
      setMain({ main: json.weather[0].main });
      setHumidity({ humidity: json.main.humidity + " %" });
      setPressure({ pressure: json.main.pressure + " hPa" });
      setVisibility({
        visibility: (json.visibility / 1000).toFixed(2) + " km",
      });
    } catch (err) {
      console.warn("error");
    }
  }
  return (
    <View style={styles.weatherBox}>
      <View style={styles.weatherHolder}>
        <Image
          source={{
            uri: "http://openweathermap.org/img/wn/" + setIcon + "@2x.png",
          }}
          style={styles.weatherImage}
        />
        <View>
          <Text style={styles.temperature}>{temp}</Text>
          <Text>{cityDisplay}</Text>
        </View>
      </View>
    </View>
  );
};

Essentially, my goal is to click the card text where it says :let's snowboard. Once clicked, it should redirect me to the weather screen where at the moment, it will show me the current temperature and the name of the city. I am not sure why it's not showing. Im assuming it has something to do with my weather screen.

I had tested out making another simple screen where it would show the values of my current state 'reviews'. I was able to click the card and redirect me to another screen where it shows the rating value and the body.

This is the first time I've dealt with apis. Any guidance would be much appreciated(:


Solution

  • I am fairly certain that you do not actually call the fetchWeather function. In the Weather component you define the function with async function fetchWeather() {...}. However, that is only a function definition. You need to actually call it like this: fetchWeather(); which I think you can do right below the definition like the example below.

    async function fetchWeather() {
        // code that you want to execute in the function
    }
    
    // Actual function call
    fetchWeather();
    

    EDIT (concerning state management):

    I would definitely recommend reading most of the React Hooks documentation to get a full grasp, but I will still address how you handle state.

    At this location in the docs it shows exactly what I believe your issue to be.

    Whenever you try to set state you do this: setVariable({ variableName: newValue});, but that is how you are supposed to set state inside of a class. However, fetchWeather() is a function, and functions are supposed to update state like this: setVariable(newValue);