API の操作、データの取得、React での async や await などの非同期関数など、重要な Web 開発スキルを習得したい場合は、天気予報アプリを構築するのが最良の学習方法です。
リアルタイムの天気や天気予報を確認できるので、楽しいプロジェクトでもあります。
このチュートリアルでは、React を使用して、あらゆる都市の天気とその都市の 5 日間の天気予報を表示する、完全に機能する天気アプリを構築します。
明日雨が降るかどうかを知ることに加えて、次の概念も学びます:
このチュートリアルが終わるまでに、次のようなアプリが構築できるようになります。
React の基礎をさらに磨き上げる必要がある場合は、このチュートリアルをお読みください:
React 入門: 初心者向け完全ガイド
始めましょう。
Vite は、より高速かつ効率的な開発エクスペリエンスを実現するために設計されたビルド ツールです。これには、非常に高速なホット モジュール交換 (HMR) などの機能を備えたネイティブ ES モジュールを強化する開発サーバーと、ロールアップを利用してコードを実稼働用に高度に最適化された静的アセットにバンドルするビルド コマンドが付属しています。
ターミナルで次のコマンドを発行すると、react-weather という新しいアプリケーションが作成されます
npm create vite@latest react-weather
次のステップでは、フレームワークとして Reat を選択し、バリアントとして JavaScript を選択します。
Vite がアプリケーションを作成したら、react-weather フォルダーに移動し、npm install および npm run コマンドを実行します。
cd react-weather npm install npm run dev
これで、アプリケーションは http://localhost:5173/
で実行されるはずです。まず、app.jsx ファイル内で UI を構築し、返されたフラグメント内のすべてのコンテンツを削除します。 app.jsx は次のようになります:
import { useState } from 'react' import './App.css' function App() { return ( <> </> ) } export default App
UI には 3 つのセクションがあります。
return ステートメント内に、ラッパー div を追加することから始めましょう。この div 要素には、すべてのセクションが含まれます:
npm create vite@latest react-weather
ラッパー内に、
を持つヘッダーを追加します。都市を表示するためのcd react-weather npm install npm run dev
詳細セクションでは、湿度と風速を連続して表示したいので、それぞれが div 要素に含まれます。
import { useState } from 'react' import './App.css' function App() { return ( <> </> ) } export default App
最後に、予測セクションには毎日のタイトルといくつかのリスト項目があります。リスト項目については、とりあえず 2 日分を表示してみましょう。
import { useState } from 'react' import './App.css' function App() { return ( <div className="wrapper"> </div> ) } export default App
これまでのところ、アプリは次のようになります:
インターフェイスを美しくするために、CSS を使用してスタイルを追加しましょう。 main.jsx ファイルには、アプリのすべてのグローバル スタイルをインポートするインポートがすでに存在します
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;
フレックスを使用してボディをスタイリングすることから始めましょう。
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> ); }
ここでは、すべてのコンテンツが水平方向と垂直方向の中央に配置されるように、justify-items:center と justify-content:center を設定しています。
ラッパーについては、別の背景色、最小幅、境界線の半径、ボックスの影、および四辺のマージンを追加しましょう。
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> ); }
都市名と温度要素のフォント サイズを大きくし、太字にします。ヘッダー要素の全体的なスタイルは次のようになります:
import './index.css'
天気の詳細セクションの要素 (つまり、湿度と風速) が同じ行に配置されるようにするには、display: flex と justify-content: space-between; を使用します。以下は、天気の詳細とその要素のスタイルです:
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; }
最後に、天気予報セクションに次のスタイルを追加します:
.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); }
アプリは次のようになります:
これまでプレースホルダー データを使用していましたが、リアルタイムの気象情報を取得するには、openweather API を使用します。 https://openweathermap.org/api にアクセスして、無料の API キーを取得します。
API_KEY を定義します。
.city { font-size: 2.5rem; font-weight: bold; } .temperature { font-size: 3.5rem; font-weight: bold; } .condition { font-size: 1.25rem; }
本番環境では、API キーなどの機密データを .env ファイルに追加する必要があります。
React では、状態はコンポーネントが動的データを管理し、それに応答できるようにするため、重要な概念です。 API からデータをフェッチするときは、コンポーネント内でそのデータを保存および操作する方法が必要です。
ここで国家が登場します。
時間の経過とともに変化する可能性のある React コンポーネント内のすべてのものは、状態によって管理されます。状態が変化すると、React コンポーネントが再レンダリングされ、新しい変更が反映されます。
たとえば、天気アプリでは、特定の都市の現在の天気情報を取得し、それを状態に保存したいと考えています。
これを行うには、useState フックを使用します。このフックの構文は次のようになります:
npm create vite@latest react-weather
アプリ機能の上部で気象データの状態を定義します。初期値はnullになります
cd react-weather npm install npm run dev
都市の州を定義し、都市名の初期状態変数をロンドンに設定します
import { useState } from 'react' import './App.css' function App() { return ( <> </> ) } export default App
デフォルトでは、React には副作用を処理する方法がありません。副作用とは、非同期操作、ローカル ストレージなど、Reacts の制御外で発生する操作です。 c .
React コンポーネントはマウント時にレンダリングされるため、フェッチ リクエストが完了するまでに時間がかかるため、この段階で API リクエストを行ってもデータにはまだアクセスできません。
そのような場合、React は useEffect フックを使用して副作用を実行します。 useEffect フックは、最初のパラメーターとして関数と依存関係配列を受け取ります。その構文は次のようになります:
import { useState } from 'react' import './App.css' function App() { return ( <div className="wrapper"> </div> ) } export default App
useEffect フックの依存関係配列には、いつエフェクトを実行するかを決定する変数が含まれています。たとえば、この場合、useEffect はレンダリングごとではなく、気象データが変化したときに実行する必要があります。
useEffect 内に、Open Weather API から特定の都市の天気を取得する非同期関数を作成します。これは非同期操作であるため、関数も非同期である必要があります。
関数はパラメータとして cityName を受け取ります
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;
データがフェッチされたら、setWeatherData セッター関数を使用して、応答データで状態を更新します。潜在的なエラーを処理するには、必ずコードを try-catch ブロックでラップしてください。
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> ); }
マウント時にデータを取得するには、useEffect 内で天気データの取得関数を呼び出す必要があります。
関数を呼び出すとき、現在の都市の値を引数として渡します。これにより、アプリが初めてマウントされるときに、都市の州で指定された値について表示するデータがすでにあることが保証されます。
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> ); }
開発者ツールでログを確認すると、レンダリングごとに複数の API リクエストが行われていることがわかります。
これは非常にコストのかかる操作です。レンダリングごとにフェッチしないようにするには、useEffect にいくつかの依存関係を提供する必要があります。これらの依存関係によって、オープンウェザー API に対する API 呼び出しがいつ行われるかが決まります。
それでは、依存関係配列に city を追加して、最初のマウント時または city の値が変更されたときにのみ API 呼び出しが行われるようにしましょう。
npm create vite@latest react-weather
データをログに記録すると、ロンドン市の天気の詳細を含むオブジェクトが取得されます。
cd react-weather npm install npm run dev
次に、JSX を使用して天気の詳細を要素に挿入しましょう。
import { useState } from 'react' import './App.css' function App() { return ( <> </> ) } export default App
JavaScript では、式条件 && は React コンポーネント内の条件付きレンダリングに使用されます。
&& 演算子は 2 つの条件をチェックし、両方の条件が true の場合にのみ true を返します。この例では、weatherData が存在する場合、指定されたデータ プロパティがレンダリングされます。
weatherData が null (または未定義) の場合、要素はレンダリングされず、null のプロパティにアクセスしようとするときに発生する可能性のあるエラーを防ぎます。
予報を取得するには、この API https://api.openweathermap.org/data/2.5/forecast?q=${CITY}&appid=${API_KEY} を使用して、同じ useEffect フックで別のフェッチ リクエストを実行します。 &units=帝国
まず、予測データを保存する予測状態を作成し、初期値を空の配列に初期化します。
import { useState } from 'react' import './App.css' function App() { return ( <div className="wrapper"> </div> ) } export default App
fetchWeatherData 関数内で、上記 API に対してフェッチリクエストを行い、応答データに予測状態を設定します。
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;
予測 API は通常、今後 5 日間の 3 時間ごとに予測を返します。その結果、40 個のデータ ポイントが生成されます。ここでは切り捨てられた出力を示します。
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> ); }
変数 dt はタイムスタンプなので、人間が判読できる時刻に変換したい場合は、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> ); }
このタイムスタンプの出力はsatです
40 個の予測項目の配列に対して、フィルター関数を使用して、指定された (項目, インデックス) => に基づいてフィルター処理しました。インデックス % 8 === 0condition.
(項目、インデックス) => Index % 8 === 0: この条件は、「インデックスが 8 で割り切れる予測のみを維持する」ことを意味します。予報は 3 時間ごとなので、8 番目の項目ごとに 1 日あたり 1 つの予報を表します (3 時間 × 8 = 24 時間)。
たとえば、インデックスの範囲が 0 ~ 39 であるとすると、8 番目ごとにインデックスが dailyForecast 配列に追加されます。合計で 5 つの気象データのインスタンスが存在します。
各天気予報データ ポイントは次のようになります:
import './index.css'
インスタンスが 5 つあるため、map() メソッドを使用して毎日の予報を反復して表示します。
次のように予測セクションを更新します:
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; }
ここでは、エラーがポップアップする原因となる空の配列をループしないように、予測配列にデータが含まれているかどうかもチェックしています。
予測データを確認した後、予測配列にマッピングし、毎日次のデータを注入します。
アプリは次のようになります:
私たちのアプリは素晴らしく見えますが、まだ動的データを取得できません。ユーザーが任意の都市に関する情報を取得できるように、上部に検索フォームを追加しましょう。
しかし、その前に、入力フィールドの状態が必要です。空文字列を初期値として状態を宣言します。
npm create vite@latest react-weather
フォームを作成し、入力を searchInput 状態にバインドし、ユーザーが新しい都市を入力したときに searchInput 値を更新する onChange イベントを追加します。
cd react-weather npm install npm run dev
フォームのスタイルは次のとおりです。
import { useState } from 'react' import './App.css' function App() { return ( <> </> ) } export default App
フォームの送信時にweatherData関数を呼び出す必要があるため、関数定義をuseEffectフックの外に移動しますが、アプリはマウント時に初期都市値のデータを表示する必要があるため、引き続きこの関数を呼び出します。
import { useState } from 'react' import './App.css' function App() { return ( <div className="wrapper"> </div> ) } export default App
ユーザーが検索フォームで都市を検索した後、新しい都市で fetchWeatherData を呼び出し、weatherData 状態を新しい都市の気象情報に更新する別の関数を呼び出す必要があります。
以下に示すように、onSubmitevent をフォームに追加し、関数を参照します。
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;
フォームが送信されると、新しい都市の気象情報が取得されます。
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> ); }
fetchWeatherData 関数はすでに WeatherData 状態の新しい状態を新しいデータで更新しているため、関数を呼び出して、ユーザー (searchInput) から新しい都市の値を渡すだけです。
API からデータを取得するときに、さまざまな問題が発生する可能性があります。たとえば、私たちの場合、天気予報 API がダウンしているか、無効な API キーがあるか、1 日あたりの API 制限を使い果たしている可能性があります。
この場合、ユーザーがサーバー エラーを経験しないように、適切なエラー処理メカニズムを追加する必要があります。
たとえば、アプリが初めて読み込まれるとき、予測配列は空になり、weatherData は null になります。優れたユーザー エクスペリエンスを確保するために、エラーと読み込み状態を追加しましょう。
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> ); }
fetchWeatherData 関数で、フェッチが行われる直前に、エラーと読み込みの初期状態を設定します
import './index.css'
catch ブロックで、エラー状態をわかりやすいメッセージに設定しましょう
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; }
JavaScript では、try catch ブロックのfinally句はクリーンアップに最適です。 API 操作の結果に関係なく、読み込み状態を削除したいと考えています。
.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); }
エラーと読み込み状態が UI に確実に反映されるようにするには、このコードを return ステートメントの直前に追加します
npm create vite@latest react-weather
エラーメッセージが発生した場合にそれを表示するには、この
を追加します。フォームの後にタグを付けます。cd react-weather npm install npm run dev
この条件により、エラーが発生した場合に、状態に保存されているエラー メッセージが表示されます。
これは読み込み中のアプリです。
エラーが発生した場合の出力は次のとおりです。
このチュートリアルは終わりました。ソースコードはここにあります。
このチュートリアルが少し難しいと感じた場合は、React の基礎をさらにブラッシュアップする必要があるかもしれません。
無料の React ガイドを入手してレベルアップしてください。
コーディングを楽しんでください。
以上がReact で天気アプリを構築する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。