Maison >interface Web >js tutoriel >Comment créer une application météo dans React
Si vous souhaitez maîtriser des compétences cruciales en développement Web, telles que l'utilisation d'API, la récupération de données et des fonctions asynchrones telles que async et wait dans React, la création d'une application météo est la meilleure façon d'apprendre.
C'est aussi un projet amusant puisque vous obtenez la météo et les prévisions météorologiques en temps réel.
Dans ce didacticiel, nous utiliserons React pour créer une application météo entièrement fonctionnelle qui affichera la météo de n'importe quelle ville et des prévisions météorologiques sur 5 jours pour la ville.
En plus de savoir s'il pleuvra demain ?, vous apprendrez également ces notions :
À la fin de ce didacticiel, vous aurez créé une application qui ressemble à ceci :
Si vous avez besoin de rafraîchir vos fondamentaux React, lisez ce tutoriel :
Démarrer avec React : guide complet du débutant
Commençons.
Vite est un outil de build conçu pour une expérience de développement plus rapide et plus efficace. Il est livré avec un serveur de développement qui améliore les modules ES natifs avec des fonctionnalités telles que le remplacement de module à chaud (HMR) extrêmement rapide et une commande de construction qui utilise Rollup pour regrouper le code dans des actifs statiques hautement optimisés pour la production.
Dans votre terminal, lancez cette commande qui créera une nouvelle application appelée React-Weather
npm create vite@latest react-weather
À l'étape suivante, sélectionnez Reat comme framework et JavaScript comme variante.
Une fois que Vite a créé l'application, placez-la dans le dossier React-Weather et exécutez les commandes npm install et npm run.
cd react-weather npm install npm run dev
Maintenant, votre application devrait être exécutée sur http://localhost:5173/
Nous allons commencer par créer l'interface utilisateur, dans votre fichier app.jsx, et supprimer tout le contenu du fragment renvoyé. Votre app.jsx devrait maintenant ressembler à ceci :
import { useState } from 'react' import './App.css' function App() { return ( <> </> ) } export default App
L'interface utilisateur comportera 3 sections.
Dans l'instruction return, commençons par ajouter un div wrapper. Cet élément div contiendra toutes les sections :
npm create vite@latest react-weather
À l'intérieur du wrapper, ajoutez un en-tête avec un
pour afficher la ville, un élément pour la température et un autre pour les conditions météorologiques globales.cd react-weather npm install npm run dev
Dans la section détails, nous souhaitons afficher l'humidité et la vitesse du vent d'affilée, donc chacun sera dans son élément div.
import { useState } from 'react' import './App.css' function App() { return ( <> </> ) } export default App
Enfin, la section prévisions aura un titre et quelques éléments de liste pour chaque jour. Pour les éléments de la liste, commençons par afficher deux jours pour l'instant.
import { useState } from 'react' import './App.css' function App() { return ( <div className="wrapper"> </div> ) } export default App
Jusqu'à présent, notre application ressemble désormais à ceci :
Pour rendre notre interface plus belle, ajoutons un peu de style, nous utiliserons CSS. Dans le fichier main.jsx, nous avons déjà cet import qui importe tous les styles globaux pour notre application
import { useState } from "react"; import "./App.css"; function App() { return ( <div className="wrapper"> <div className="header"> <h1 className="city">London</h1> <p className="temperature">60°F</p> <p className="condition">Cloudy</p> </div> </div> ); } export default App;
Commençons par styliser le corps en utilisant le flex.
export default App; import { useState } from "react"; import "./App.css"; function App() { return ( <div className="wrapper"> <div className="header"> <h1 className="city">London</h1> <p className="temperature">60°F</p> <p className="condition">Cloudy</p> </div> <div className="weather-details"> <div> <p>Humidity</p> <p> 60%</p> </div> <div> <p>Wind Speed</p> <p>7 mph</p> </div> </div> </div> ); }
Ici, nous avons défini justifier-items:center et justifier-content:centerpour garantir que tout le contenu est centré horizontalement et verticalement.
Pour le wrapper, ajoutons une couleur d'arrière-plan différente, une largeur minimale, une bordure rayonnante et une ombre de boîte, ainsi qu'une marge de tous les côtés.
export default App; import { useState } from "react"; import "./App.css"; function App() { return ( <div className="wrapper"> <div className="header"> <h1 className="city">London</h1> <p className="temperature">60°F</p> <p className="condition">Cloudy</p> </div> <div className="weather-details"> <div> <p>Humidity</p> <p> 60%</p> </div> <div> <p>Wind Speed</p> <p>7 mph</p> </div> </div> <div className="forecast"> <h2 className="forecast-header">5-Day Forecast</h2> <div className="forecast-days"> <div className="forecast-day"> <p>Monday</p> <p>Cloudy</p> <p>12°F</p> </div> <div className="forecast-day"> <p>Monday</p> <p>Cloudy</p> <p>12°F</p> </div> </div> </div> </div> ); }
Ajoutez une taille de police plus grande aux éléments de nom de la ville et de température et mettez-les en gras. Les styles généraux des éléments d'en-tête ressembleront à ceci :
import './index.css'
Pour vous assurer que les éléments de la section des détails météorologiques (c'est-à-dire l'humidité et la vitesse du vent) sont alignés sur la même ligne, utilisez display: flex et justifier-content: space-between; Voici les styles pour les détails météo et ses éléments :
body { min-height: 100vh; background: linear-gradient(to bottom right, #60a5fa, #3b82f6); display: flex; align-items: center; justify-content: center; padding: 1rem; font-family: Arial, sans-serif; }
Enfin, pour la section prévisions météo, ajoutez les styles suivants :
.wrapper { background: rgba(255, 255, 255, 0.2); border-radius: 1.5rem; padding: 2rem; min-width: 400px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); }
Maintenant, notre application ressemble à ceci :
Jusqu'à présent, nous utilisons des données d'espace réservé, pour obtenir des informations météorologiques en temps réel, nous utiliserons l'API openweather. Rendez-vous sur https://openweathermap.org/api et obtenez une clé API GRATUITE.
Définissez l'API_KEY.
.city { font-size: 2.5rem; font-weight: bold; } .temperature { font-size: 3.5rem; font-weight: bold; } .condition { font-size: 1.25rem; }
Dans un environnement de production, vous devez ajouter des données sensibles telles que des clés API dans un fichier .env.
Dans React, l'état est un concept crucial car il permet aux composants de gérer et de répondre aux données dynamiques. Lorsque vous récupérez des données à partir d'une API, vous avez besoin d'un moyen de stocker et de manipuler ces données dans votre composant.
C'est là qu'intervient l'État.
Tout ce qui peut changer dans un composant React au fil du temps est géré par l'État. Lorsque l'état change, le composant React s'affichera à nouveau et reflétera les nouveaux changements.
Par exemple, dans notre application météo, nous souhaitons obtenir les informations météorologiques actuelles pour une ville spécifique et les stocker dans l'État.
Pour ce faire, nous utiliserons le hook useState. La syntaxe de ce hook ressemble à ceci :
npm create vite@latest react-weather
Définissez l'état des données météorologiques en haut de la fonction App. La valeur initiale sera nulle
cd react-weather npm install npm run dev
Définissez l'état de la ville et définissez la variable d'état initiale du nom de la ville sur Londres
import { useState } from 'react' import './App.css' function App() { return ( <> </> ) } export default App
React par défaut n'a aucun moyen de gérer les effets secondaires. Les effets secondaires sont des opérations qui se produisent en dehors du contrôle de Reacts, telles que les opérations asynchrones, le stockage local, etc. c .
Étant donné que les composants React s'affichent lors de leur montage, faire une requête API à ce stade n'aura pas encore accès aux données car une requête d'extraction prend du temps.
Dans de tels cas, React utilise le hook useEffect pour effectuer des effets secondaires. Le hook useEffect prend une fonction comme premier paramètre et un tableau de dépendances. Sa syntaxe ressemble à ceci :
import { useState } from 'react' import './App.css' function App() { return ( <div className="wrapper"> </div> ) } export default App
Le tableau de dépendances du hook useEffect contient des variables qui déterminent quand l'effet doit s'exécuter. Par exemple, dans notre cas, useEffect devrait s'exécuter lorsque les données météorologiques changent plutôt qu'à chaque rendu.
Dans useEffect, créez une fonction asynchrone qui récupérera la météo d'une ville spécifique à partir de l'API météo ouverte. Puisqu'il s'agit d'une opération asynchrone, notre fonction devrait également être asynchrone.
La fonction prend le cityName comme paramètre
import { useState } from "react"; import "./App.css"; function App() { return ( <div className="wrapper"> <div className="header"> <h1 className="city">London</h1> <p className="temperature">60°F</p> <p className="condition">Cloudy</p> </div> </div> ); } export default App;
Une fois les données récupérées, utilisez la fonction setWeatherData pour mettre à jour l'état avec les données de réponse. Assurez-vous d'envelopper votre code dans un bloc try-catch pour gérer toute erreur potentielle.
export default App; import { useState } from "react"; import "./App.css"; function App() { return ( <div className="wrapper"> <div className="header"> <h1 className="city">London</h1> <p className="temperature">60°F</p> <p className="condition">Cloudy</p> </div> <div className="weather-details"> <div> <p>Humidity</p> <p> 60%</p> </div> <div> <p>Wind Speed</p> <p>7 mph</p> </div> </div> </div> ); }
Pour que les données soient récupérées lors du montage, nous devons invoquer la fonction de récupération des données météorologiques à l'intérieur de useEffect.
Lors de l'appel de la fonction, nous passerons la valeur de la ville actuelle comme argument. Cela garantira que lorsque l'application est montée pour la première fois, nous disposons déjà de certaines données à afficher pour la valeur spécifiée dans la ville-état.
export default App; import { useState } from "react"; import "./App.css"; function App() { return ( <div className="wrapper"> <div className="header"> <h1 className="city">London</h1> <p className="temperature">60°F</p> <p className="condition">Cloudy</p> </div> <div className="weather-details"> <div> <p>Humidity</p> <p> 60%</p> </div> <div> <p>Wind Speed</p> <p>7 mph</p> </div> </div> <div className="forecast"> <h2 className="forecast-header">5-Day Forecast</h2> <div className="forecast-days"> <div className="forecast-day"> <p>Monday</p> <p>Cloudy</p> <p>12°F</p> </div> <div className="forecast-day"> <p>Monday</p> <p>Cloudy</p> <p>12°F</p> </div> </div> </div> </div> ); }
Si vous vérifiez les journaux avec vos outils de développement, vous verrez que nous effectuons plusieurs requêtes API à chaque rendu.
Il s'agit d'une opération très coûteuse, pour éviter la récupération à chaque rendu, nous devons fournir certaines dépendances à useEffect. Ces dépendances détermineront le moment où un appel d'API sera effectué vers l'API météo ouverte.
Ajoutons donc city dans le tableau de dépendances pour garantir que les appels d'API ne seront effectués que lors du premier montage ou lorsque la valeur de city change.
npm create vite@latest react-weather
Lorsque nous enregistrons les données, nous obtenons un objet contenant les détails météorologiques de la ville de Londres.
cd react-weather npm install npm run dev
Injectons maintenant les détails météorologiques dans les éléments à l'aide de JSX.
import { useState } from 'react' import './App.css' function App() { return ( <> </> ) } export default App
En JavaScript, la condition d'expression && est utilisée pour le rendu conditionnel dans les composants React.
L'opérateur && vérifie deux conditions et renvoie vrai uniquement si les deux conditions sont vraies. Dans notre cas, si WeatherDataexiste, les propriétés de données spécifiées seront rendues.
Si WeatherData est nul (ou non défini), les éléments ne seront pas rendus, empêchant ainsi toute erreur qui pourrait survenir en essayant d'accéder aux propriétés de null.
Pour obtenir les prévisions, nous ferons une autre requête de récupération dans le même useEffect Hook en utilisant cette API https://api.openweathermap.org/data/2.5/forecast?q=${CITY}&appid=${API_KEY} &unités=impérial
Tout d'abord, créez un état de prévision pour stocker les données de prévision et initialisez la valeur initiale sur un tableau vide.
import { useState } from 'react' import './App.css' function App() { return ( <div className="wrapper"> </div> ) } export default App
Dans la fonction fetchWeatherData, effectuez une requête de récupération à l'API ci-dessus et définissez l'état de prévision sur les données de réponse.
import { useState } from "react"; import "./App.css"; function App() { return ( <div className="wrapper"> <div className="header"> <h1 className="city">London</h1> <p className="temperature">60°F</p> <p className="condition">Cloudy</p> </div> </div> ); } export default App;
L'API de prévision renvoie généralement les prévisions toutes les 3 heures pour les 5 prochains jours, ce qui donne 40 points de données. Voici la sortie tronquée.
export default App; import { useState } from "react"; import "./App.css"; function App() { return ( <div className="wrapper"> <div className="header"> <h1 className="city">London</h1> <p className="temperature">60°F</p> <p className="condition">Cloudy</p> </div> <div className="weather-details"> <div> <p>Humidity</p> <p> 60%</p> </div> <div> <p>Wind Speed</p> <p>7 mph</p> </div> </div> </div> ); }
La variable dt est un horodatage, donc si nous voulons la convertir en une heure lisible par l'homme en utilisant la méthode toLocaleDateString().
export default App; import { useState } from "react"; import "./App.css"; function App() { return ( <div className="wrapper"> <div className="header"> <h1 className="city">London</h1> <p className="temperature">60°F</p> <p className="condition">Cloudy</p> </div> <div className="weather-details"> <div> <p>Humidity</p> <p> 60%</p> </div> <div> <p>Wind Speed</p> <p>7 mph</p> </div> </div> <div className="forecast"> <h2 className="forecast-header">5-Day Forecast</h2> <div className="forecast-days"> <div className="forecast-day"> <p>Monday</p> <p>Cloudy</p> <p>12°F</p> </div> <div className="forecast-day"> <p>Monday</p> <p>Cloudy</p> <p>12°F</p> </div> </div> </div> </div> ); }
La sortie pour cet horodatage est sat
Donc, pour le tableau de 40 éléments de prévision, nous avons utilisé la fonction de filtre pour filtrer en fonction du (élément, index) => indice % 8 === 0condition.
(élément, index) => index % 8 === 0 : Cette condition signifie : "Ne conserver la prévision que là où l'indice est divisible par 8." Puisque la prévision est toutes les 3 heures, un élément sur 8 représente une prévision par jour (3 heures × 8 = 24 heures).
Ainsi, par exemple, étant donné que les indices vont de 0 à 39, un indice sur 8 est ajouté au tableau dailyForecast. Au total, nous aurons 5 instances de données météorologiques.
Chaque point de données de prévisions météorologiques ressemble à ceci :
import './index.css'
Comme nous avons 5 instances, nous utiliserons la méthode map() pour itérer et afficher les prévisions pour chaque jour.
Mettez à jour la section des prévisions comme suit :
body { min-height: 100vh; background: linear-gradient(to bottom right, #60a5fa, #3b82f6); display: flex; align-items: center; justify-content: center; padding: 1rem; font-family: Arial, sans-serif; }
Ici, nous vérifions également si le tableau de prévisions contient des données pour nous assurer de ne pas boucler sur un tableau vide, ce qui entraînerait l'apparition d'erreurs.
Après avoir vérifié les données de prévision, nous cartographions le tableau de prévisions et injectons les données suivantes pour chaque jour.
Maintenant, notre application ressemble à ceci :
Notre application a fière allure, mais nous ne parvenons toujours pas à récupérer des données dynamiques. Ajoutons un formulaire de recherche en haut pour permettre aux utilisateurs d'obtenir des informations sur n'importe quelle ville.
Mais d’abord, nous avons besoin d’un état pour le champ de saisie. Déclarez l'état avec une chaîne vide comme valeur initiale.
npm create vite@latest react-weather
Créez le formulaire, liez l'entrée à l'état searchInput et ajoutez l'événement onChange qui mettra à jour la valeur searchInput lorsque l'utilisateur tape une nouvelle ville.
cd react-weather npm install npm run dev
Voici les styles du formulaire.
import { useState } from 'react' import './App.css' function App() { return ( <> </> ) } export default App
Puisque nous devons invoquer la fonction WeatherData lorsque le formulaire est soumis, nous allons déplacer la définition de la fonction en dehors du hook useEffect mais nous l'appellerons quand même car l'application doit afficher certaines données pour la valeur initiale de la ville lors de son montage.
import { useState } from 'react' import './App.css' function App() { return ( <div className="wrapper"> </div> ) } export default App
Après qu'un utilisateur ait recherché une ville avec un formulaire de recherche, nous devons appeler une autre fonction qui invoquera fetchWeatherData avec la nouvelle ville et mettra à jour l'état WeatherData avec les informations météorologiques de la nouvelle ville.
Ajoutez un onSubmitevent au formulaire et référencez la fonction comme indiqué ci-dessous.
import { useState } from "react"; import "./App.css"; function App() { return ( <div className="wrapper"> <div className="header"> <h1 className="city">London</h1> <p className="temperature">60°F</p> <p className="condition">Cloudy</p> </div> </div> ); } export default App;
Lorsque le formulaire sera soumis, il récupérera les informations météorologiques de la nouvelle ville.
export default App; import { useState } from "react"; import "./App.css"; function App() { return ( <div className="wrapper"> <div className="header"> <h1 className="city">London</h1> <p className="temperature">60°F</p> <p className="condition">Cloudy</p> </div> <div className="weather-details"> <div> <p>Humidity</p> <p> 60%</p> </div> <div> <p>Wind Speed</p> <p>7 mph</p> </div> </div> </div> ); }
Étant donné que la fonction fetchWeatherData met déjà à jour le nouvel état de l'état WeatherData avec les nouvelles données, nous invoquons uniquement la fonction et transmettons la valeur de la nouvelle ville à l'utilisateur (searchInput).
Lors de la récupération des données de l'API, divers problèmes peuvent survenir. Par exemple, dans notre cas, l'API météo peut être en panne, ou nous pouvons avoir une clé API non valide, ou nous pouvons avoir épuisé notre limite quotidienne d'API.
Dans ce cas, nous devons ajouter un mécanisme de gestion des erreurs approprié afin que l'utilisateur ne rencontre pas d'erreurs de serveur.
Par exemple, lorsque l'application se charge pour la première fois, le tableau de prévisions sera vide et les données météorologiques seront nulles. Pour garantir une bonne expérience utilisateur, ajoutons des états d'erreur et de chargement.
export default App; import { useState } from "react"; import "./App.css"; function App() { return ( <div className="wrapper"> <div className="header"> <h1 className="city">London</h1> <p className="temperature">60°F</p> <p className="condition">Cloudy</p> </div> <div className="weather-details"> <div> <p>Humidity</p> <p> 60%</p> </div> <div> <p>Wind Speed</p> <p>7 mph</p> </div> </div> <div className="forecast"> <h2 className="forecast-header">5-Day Forecast</h2> <div className="forecast-days"> <div className="forecast-day"> <p>Monday</p> <p>Cloudy</p> <p>12°F</p> </div> <div className="forecast-day"> <p>Monday</p> <p>Cloudy</p> <p>12°F</p> </div> </div> </div> </div> ); }
Dans la fonction fetchWeatherData, juste avant toute récupération, définissez les états initiaux d'erreur et de chargement
import './index.css'
Dans le bloc catch, définissons l'état d'erreur sur un message convivial
body { min-height: 100vh; background: linear-gradient(to bottom right, #60a5fa, #3b82f6); display: flex; align-items: center; justify-content: center; padding: 1rem; font-family: Arial, sans-serif; }
En JavaScript, la clause final du bloc try catch est idéale pour le nettoyage. Quel que soit le résultat de l'opération API, nous souhaitons supprimer l'état de chargement.
.wrapper { background: rgba(255, 255, 255, 0.2); border-radius: 1.5rem; padding: 2rem; min-width: 400px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); }
Pour garantir que les états d'erreur et de chargement sont reflétés dans l'interface utilisateur, ajoutez ce code juste avant l'instruction return
npm create vite@latest react-weather
Pour afficher le message d'erreur s'il se produit, ajoutez ceci
tag après le formulaire.cd react-weather npm install npm run dev
Cette condition garantit que si une erreur se produit, le message d'erreur stocké dans l'état sera affiché.
Voici l'application en état de chargement.
Voici le résultat lorsqu'une erreur se produit.
Nous sommes arrivés à la fin de ce tutoriel. Vous pouvez trouver le code source ici.
Si vous avez trouvé ce tutoriel un peu difficile, vous devrez peut-être revoir vos principes fondamentaux de React.
Obtenez mon guide React gratuit et passez au niveau supérieur.
Bon codage.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!