You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native应用:通过OpenWeatherMap API获取并展示天气数据

如何在React Native中使用OpenWeatherMap API获取天气数据

我有一个React Native天气卡片组件,目前已完成样式部分,但天气数据(当前/最高/最低温度、天气状况、图标)均为硬编码。需要接入OpenWeatherMap API获取实时数据,现有代码如下:

现有代码

Weather Card组件

// Weather Card

...
const TemperatureCardSmall = (props) => {
  var apiKey = API_KEY;
    
  var weather = "Clear";

  return (
    <Card style={{ ...styles.tempCard, ...props.styles }}>
      <View style={styles.topContainer}>
        <View style={styles.imageContainer}>
          <Ionicons
            size={45}
            style={styles.conditionIcon}
            name={weatherConditions[weather].icon}
            color={"#fff"}
          />
        </View>
        <View style={styles.currentContainer}>
          <Text style={styles.currentText}>12&deg;</Text>
        </View>
      </View>

      <View style={styles.bottomContainer}>
        <View style={styles.textContainer}>
          <Text style={styles.conditionText}>
            {weatherConditions[weather].title}
          </Text>
          <View>
            <Text style={styles.subtitleText}>H: 13&deg; L: 10&deg;</Text>
          </View>
        </View>
      </View>
    </Card>
  );
};
...

WeatherConditions.js

export const weatherConditions = {
  Rain: {
    title: "Rainy",
    icon: "rainy",
  },

  Clear: {
    title: "Sunny",
    icon: "sunny",
  },

  Thunderstorm: {
    title: "Thunderstorm",
    icon: "thunderstorm",
  },

  Clouds: {
    title: "Cloudy",
    icon: "cloudy",
  },

  Drizzle: {
    title: "Drizzle",
    icon: "water",
  },

  Mist: {
    title: "Misty",
    icon: "filter",
  },

  Snow: {
    title: "Snowy",
    icon: "snow",
  },
};

实现步骤

1. 获取OpenWeatherMap API密钥

注册OpenWeatherMap账号,在个人控制台获取API密钥(记为API_KEY)。

2. 安装网络请求库

推荐使用axios简化网络请求:

npm install axios
# 或
yarn add axios

3. 重构组件,添加状态管理

将组件改为带状态的函数式组件,用useState存储天气数据、加载状态和错误信息,用useEffect触发API请求:

import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { View, Text } from 'react-native';
import { Card } from 'react-native-paper';
import Ionicons from '@expo/vector-icons/Ionicons';
import { weatherConditions } from './WeatherConditions';

const TemperatureCardSmall = (props) => {
  const [weatherData, setWeatherData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const API_KEY = '你的API密钥'; // 替换为实际密钥
  const CITY_NAME = 'Beijing'; // 可改为props传入动态城市

  // 发起API请求
  useEffect(() => {
    const fetchWeatherData = async () => {
      try {
        const response = await axios.get(
          `https://api.openweathermap.org/data/2.5/weather?q=${CITY_NAME}&appid=${API_KEY}&units=metric`
        );
        setWeatherData(response.data);
        setError(null);
      } catch (err) {
        setError('获取天气数据失败');
        console.error(err);
      } finally {
        setLoading(false);
      }
    };

    fetchWeatherData();
  }, []);

  // 加载状态渲染
  if (loading) {
    return (
      <Card style={{ ...styles.tempCard, ...props.styles }}>
        <Text style={styles.loadingText}>加载中...</Text>
      </Card>
    );
  }

  // 错误状态渲染
  if (error) {
    return (
      <Card style={{ ...styles.tempCard, ...props.styles }}>
        <Text style={styles.errorText}>{error}</Text>
      </Card>
    );
  }

  // 解析API返回数据
  const currentWeather = weatherData.weather[0].main;
  const currentTemp = Math.round(weatherData.main.temp);
  const maxTemp = Math.round(weatherData.main.temp_max);
  const minTemp = Math.round(weatherData.main.temp_min);

  return (
    <Card style={{ ...styles.tempCard, ...props.styles }}>
      <View style={styles.topContainer}>
        <View style={styles.imageContainer}>
          <Ionicons
            size={45}
            style={styles.conditionIcon}
            name={weatherConditions[currentWeather]?.icon || 'help-circle'}
            color={"#fff"}
          />
        </View>
        <View style={styles.currentContainer}>
          <Text style={styles.currentText}>{currentTemp}&deg;</Text>
        </View>
      </View>

      <View style={styles.bottomContainer}>
        <View style={styles.textContainer}>
          <Text style={styles.conditionText}>
            {weatherConditions[currentWeather]?.title || currentWeather}
          </Text>
          <View>
            <Text style={styles.subtitleText}>H: {maxTemp}&deg; L: {minTemp}&deg;</Text>
          </View>
        </View>
      </View>
    </Card>
  );
};

// 保留原样式定义,补充状态相关样式
const styles = {
  tempCard: {
    // 你的原有样式
  },
  topContainer: {
    // 你的原有样式
  },
  // ...其他原有样式
  loadingText: {
    textAlign: 'center',
    padding: 20,
    fontSize: 16,
  },
  errorText: {
    textAlign: 'center',
    padding: 20,
    fontSize: 16,
    color: '#ff3b30',
  },
};

export default TemperatureCardSmall;

4. 关键说明

  • API参数:units=metric返回摄氏度,需华氏度可改为imperial;也可通过lat/lon经纬度参数定位城市
  • 数据匹配:OpenWeatherMap返回的weather[0].main字段对应weatherConditions的key,若API返回新天气类型,需在weatherConditions中补充
  • 容错处理:使用?.可选链避免未匹配天气类型导致崩溃,同时提供默认图标和文本
  • 状态优化:通过loading和error状态提升用户体验,避免空白或错误渲染

内容的提问来源于stack exchange,提问作者David Guri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 00:06:25