Hi i am making a WeatherApp for my school project using React Native, this is my first time using React Native and i have a input field to search up the city/ country however when you try to type into the input field after you type 1 single character the keyboard disappears and i have no idea why, could someone please help me?
this is my code (i removed the API key on purpose to put it here):
import React, { useState, useEffect } from "react";
import {
StyleSheet,
Text,
View,
TextInput,
TouchableOpacity,
Alert,
Image,
ScrollView,
Button,
} from "react-native";
import axios from "axios";
import { LinearGradient } from "expo-linear-gradient";
import { NavigationContainer } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
const API_KEY = "";
export default function App() {
const [city, setCity] = useState("");
const [weather, setWeather] = useState(null);
const [main, setMain] = useState(null);
const [earthquakeData, setEarthquakeData] = useState(null);
const [forecastList, setForecastList] = useState(null);
const fetchWeather = async () => {
try {
const response = await axios.get(
`http://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${API_KEY}&units=metric`
);
setWeather(response.data);
const mainData = response.data.main;
setMain(mainData);
} catch (error) {
Alert.alert("Error", "City not found");
}
};
const forecastWeather = async () => {
try {
const response = await axios.get(
`http://api.openweathermap.org/data/2.5/forecast?q=${city}&appid=${API_KEY}&units=metric`
);
console.log(response);
const listData = response.data;
setForecastList(listData);
} catch (error) {
Alert.Alert("Cant find the forecast");
}
};
useEffect(() => {
const fetchEarthquakeData = async () => {
try {
const response = await axios.get(
"https://earthquake.usgs.gov/fdsnws/event/1/query",
{
params: {
format: "geojson",
limit: 5,
orderby: "time",
},
}
);
setEarthquakeData(response.data);
} catch (error) {
console.error("Error fetching earthquake data:", error);
}
};
fetchEarthquakeData();
}, []);
const iconMapping = {
"01d": require("./media/01d.png"),
"01n": require("./media/01n.png"),
"02d": require("./media/02d.png"),
"02n": require("./media/02n.png"),
"03d": require("./media/03d.png"),
"03n": require("./media/03n.png"),
"04d": require("./media/04d.png"),
"04n": require("./media/04n.png"),
"09d": require("./media/09d.png"),
"09n": require("./media/09n.png"),
"10d": require("./media/10d.png"),
"10n": require("./media/10n.png"),
"11d": require("./media/11d.png"),
"11n": require("./media/11n.png"),
"13d": require("./media/13d.png"),
"13n": require("./media/13n.png"),
"50d": require("./media/50d.png"),
"50n": require("./media/50n.png"),
};
function HomeScreen({ navigation }) {
return (
<View style={styles.container}>
<LinearGradient
colors={["#1C2547", "#503F9D", "#8250AC"]}
style={{ flex: 1 }}>
<View
style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Image
style={styles.homeImage}
source={require("./media/home-image2.png")}></Image>
<Text style={styles.bigText1}>EarthSky</Text>
<Text style={styles.bigText2}>Weather</Text>
<TouchableOpacity
style={styles.homeButton}
onPress={() => navigation.navigate("test")}>
<Text style={styles.homeButtonText}>Get Weather</Text>
</TouchableOpacity>
</View>
</LinearGradient>
</View>
);
}
function WeatherDetails() {
return (
<ScrollView style={styles.ScrollView}>
<View style={styles.container}>
<LinearGradient
colors={["#5735b2", "#4d32a4", "#4b31a2", "#462f9a"]}
locations={[0.07, 0.37, 0.61, 0.84]}
style={styles.linearGradient}>
<View style={styles.bigContainer}>
<Text style={styles.title}>Weather App</Text>
<TextInput
style={styles.input}
placeholder="Search for a place"
placeholderTextColor="#EBEBF5"
value={city}
onChangeText={setCity}
/>
<TouchableOpacity
style={styles.button}
onPress={() => {
fetchWeather();
forecastWeather();
}}>
<Text style={styles.buttonText}>Get Weather</Text>
</TouchableOpacity>
{weather && main && (
<View style={styles.weatherContainer}>
<View style={styles.left}>
<Text style={styles.weatherTempText}>
{parseFloat(weather.main.temp).toFixed(0)}°
</Text>
<View>
<Text style={styles.weatherMaxLowText}>
H: {main.temp_max}° L: {main.temp_min}°
</Text>
<Text style={styles.weatherText}>
{weather.name}, {weather.sys.country}{" "}
</Text>
</View>
</View>
<View style={styles.right}>
<Image
source={iconMapping[weather.weather[0].icon]}
style={styles.image}
/>
<Text style={styles.weatherText}>
{weather.weather[0].main}
</Text>
</View>
</View>
)}
<View>
{forecastList && forecastList.list && (
<>
<Text style={styles.title}>7-Day Forecast</Text>
<ScrollView horizontal>
{forecastList.list.map((forecast, index) => (
<LinearGradient
key={index}
colors={["#1C2547", "#503F9D", "#8250AC"]}
style={ styles.forecastContainer }>
<Text style={styles.forecastText}>
{parseFloat(forecast.main.temp).toFixed(0)}°
</Text>
<Image
source={iconMapping[forecast.weather[0].icon]}
style={styles.forecastImage}
/>
<Text style={styles.forecastTempText}>
{forecast.dt_txt.split(" ")[0]}
</Text>
</LinearGradient>
))}
</ScrollView>
</>
)}
</View>
<View>
<Text style={styles.title}>Top 5 Most Recent Earthquakes</Text>
{earthquakeData ? (
earthquakeData.features.map((earthquake, index) => (
<View key={index} style={styles.earthquakeContainer}>
<View style={styles.left2}>
<Text style={styles.magnitude}>
{parseFloat(earthquake.properties.mag).toFixed(1)}
</Text>
</View>
<View style={styles.right2}>
<Text style={styles.name}>
{earthquake.properties.place}
</Text>
<Text style={styles.location}>
{earthquake.geometry.coordinates[1]},{" "}
{earthquake.geometry.coordinates[0]}
</Text>
<Text style={styles.depth}>
{earthquake.geometry.coordinates[2]} km
</Text>
</View>
</View>
))
) : (
<Text>Loading...</Text>
)}
</View>
</View>
</LinearGradient>
</View>
</ScrollView>
);
}
function DetailsScreen() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Details Screen</Text>
</View>
);
}
const Stack = createNativeStackNavigator();
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Weather App">
<Stack.Screen
name="Go Back"
component={HomeScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="test"
component={WeatherDetails}
options={{
headerTintColor: "#fff",
headerTitle: " ",
headerTransparent: true,
hideWhenScrolling: false,
headerBlurEffect: "regular",
}}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
user24631294 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.