In this project, we will build a Weather App using React Native. This app will fetch weather data from an API and display it to the user. This project will help you understand how to integrate APIs, manage state, and handle user input in a real-world application.

Objectives

  • Fetch data from a weather API.
  • Display weather information to the user.
  • Handle user input to search for different cities.
  • Manage state using React hooks.

Prerequisites

Before starting this project, make sure you are familiar with the following concepts:

  • Basic React Native components and styling.
  • State and lifecycle methods.
  • Fetching data from APIs.
  • Handling user input.

Step-by-Step Guide

Step 1: Setting Up the Project

  1. Create a new React Native project:

    npx react-native init WeatherApp
    cd WeatherApp
    
  2. Install necessary dependencies:

    npm install axios
    

Step 2: Fetching Weather Data

  1. Create a new file WeatherService.js to handle API requests:

    // WeatherService.js
    import axios from 'axios';
    
    const API_KEY = 'your_api_key_here';
    const BASE_URL = 'http://api.openweathermap.org/data/2.5/weather';
    
    export const fetchWeather = async (city) => {
      try {
        const response = await axios.get(`${BASE_URL}?q=${city}&appid=${API_KEY}&units=metric`);
        return response.data;
      } catch (error) {
        console.error(error);
        throw error;
      }
    };
    
  2. Replace your_api_key_here with your actual API key from OpenWeatherMap.

Step 3: Creating the Main Component

  1. Create a new file WeatherApp.js:
    // WeatherApp.js
    import React, { useState } from 'react';
    import { View, Text, TextInput, Button, StyleSheet } from 'react-native';
    import { fetchWeather } from './WeatherService';
    
    const WeatherApp = () => {
      const [city, setCity] = useState('');
      const [weather, setWeather] = useState(null);
      const [error, setError] = useState('');
    
      const handleFetchWeather = async () => {
        try {
          const data = await fetchWeather(city);
          setWeather(data);
          setError('');
        } catch (err) {
          setError('City not found');
          setWeather(null);
        }
      };
    
      return (
        <View style={styles.container}>
          <Text style={styles.title}>Weather App</Text>
          <TextInput
            style={styles.input}
            placeholder="Enter city"
            value={city}
            onChangeText={setCity}
          />
          <Button title="Get Weather" onPress={handleFetchWeather} />
          {error ? <Text style={styles.error}>{error}</Text> : null}
          {weather && (
            <View style={styles.weatherContainer}>
              <Text style={styles.weatherText}>Temperature: {weather.main.temp}°C</Text>
              <Text style={styles.weatherText}>Humidity: {weather.main.humidity}%</Text>
              <Text style={styles.weatherText}>Condition: {weather.weather[0].description}</Text>
            </View>
          )}
        </View>
      );
    };
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        padding: 16,
      },
      title: {
        fontSize: 24,
        marginBottom: 16,
      },
      input: {
        height: 40,
        borderColor: 'gray',
        borderWidth: 1,
        marginBottom: 16,
        paddingHorizontal: 8,
        width: '80%',
      },
      weatherContainer: {
        marginTop: 16,
        alignItems: 'center',
      },
      weatherText: {
        fontSize: 18,
      },
      error: {
        color: 'red',
        marginTop: 16,
      },
    });
    
    export default WeatherApp;
    

Step 4: Integrating the Main Component

  1. Update App.js to use the WeatherApp component:
    // App.js
    import React from 'react';
    import WeatherApp from './WeatherApp';
    
    const App = () => {
      return <WeatherApp />;
    };
    
    export default App;
    

Step 5: Running the App

  1. Run the app on your emulator or device:
    npx react-native run-android
    # or
    npx react-native run-ios
    

Practical Exercises

  1. Exercise 1: Add More Weather Details

    • Extend the app to display additional weather details such as wind speed and pressure.
  2. Exercise 2: Improve Error Handling

    • Enhance the error handling to provide more specific error messages based on different error scenarios.
  3. Exercise 3: Add Loading Indicator

    • Implement a loading indicator to show while the weather data is being fetched.

Solutions

  1. Solution to Exercise 1:

    // Add the following lines in the weatherContainer View in WeatherApp.js
    <Text style={styles.weatherText}>Wind Speed: {weather.wind.speed} m/s</Text>
    <Text style={styles.weatherText}>Pressure: {weather.main.pressure} hPa</Text>
    
  2. Solution to Exercise 2:

    // Update the handleFetchWeather function in WeatherApp.js
    const handleFetchWeather = async () => {
      try {
        const data = await fetchWeather(city);
        setWeather(data);
        setError('');
      } catch (err) {
        if (err.response && err.response.status === 404) {
          setError('City not found');
        } else {
          setError('An error occurred. Please try again.');
        }
        setWeather(null);
      }
    };
    
  3. Solution to Exercise 3:

    // Add a loading state in WeatherApp.js
    const [loading, setLoading] = useState(false);
    
    // Update the handleFetchWeather function
    const handleFetchWeather = async () => {
      setLoading(true);
      try {
        const data = await fetchWeather(city);
        setWeather(data);
        setError('');
      } catch (err) {
        if (err.response && err.response.status === 404) {
          setError('City not found');
        } else {
          setError('An error occurred. Please try again.');
        }
        setWeather(null);
      } finally {
        setLoading(false);
      }
    };
    
    // Add a loading indicator in the render method
    {loading && <Text>Loading...</Text>}
    

Conclusion

In this project, you learned how to build a Weather App using React Native. You integrated a weather API, managed state, and handled user input. This project provided a practical example of how to apply the concepts learned in the previous modules. Continue to experiment and enhance the app to solidify your understanding and skills in React Native development.

© Copyright 2024. All rights reserved