Jika anda ingin menguasai kemahiran pembangunan web yang penting seperti bekerja dengan API, mengambil data dan fungsi tak segerak seperti async dan tunggu dalam React, maka membina apl cuaca ialah cara terbaik untuk belajar.
Ia juga merupakan projek yang menyeronokkan kerana anda dapat melihat ramalan cuaca dan cuaca masa nyata.
Dalam tutorial ini, kami akan menggunakan React untuk membina apl cuaca berfungsi sepenuhnya yang akan menunjukkan cuaca untuk mana-mana bandar dan sebagai ramalan cuaca 5 hari untuk bandar itu.
Selain mengetahui sama ada esok akan hujan ?, anda juga akan mempelajari konsep ini:
Menjelang akhir tutorial ini, anda akan membina apl yang kelihatan seperti ini:
Jika anda perlu mempelajari asas React anda, baca Tutorial ini:
Bermula dengan React: Panduan Lengkap Pemula
Mari kita mulakan.
Vite ialah alat binaan yang direka untuk pengalaman pembangunan yang lebih pantas dan cekap. Ia datang dengan pelayan pembangun yang meningkatkan modul ES asli dengan keupayaan seperti Penggantian Modul Panas (HMR) yang sangat pantas dan arahan binaan yang menggunakan Rollup untuk menggabungkan kod ke dalam aset statik yang sangat dioptimumkan untuk pengeluaran.
Dalam terminal anda, keluarkan arahan ini yang akan mencipta aplikasi baharu yang dipanggil react-weather
npm create vite@latest react-weather
Dalam langkah seterusnya, pilih Reat sebagai rangka kerja dan JavaScript sebagai varian.
Setelah Vite mencipta aplikasi, cd ke dalam folder cuaca tindak balas dan jalankan arahan npm install dan npm run.
cd react-weather npm install npm run dev
Sekarang aplikasi anda sepatutnya berjalan di http://localhost:5173/
Kami akan bermula dengan membina UI, dalam fail app.jsx anda dan memadamkan semua kandungan dalam serpihan yang dikembalikan. App.jsx anda kini sepatutnya kelihatan seperti ini:
import { useState } from 'react' import './App.css' function App() { return ( <> </> ) } export default App
UI akan mempunyai 3 bahagian.
Di dalam penyata pulangan, mari mulakan dengan menambah div pembalut. Elemen div ini akan mengandungi semua bahagian:
npm create vite@latest react-weather
Di dalam pembungkus, tambahkan pengepala dengan
untuk memaparkan bandar, elemen untuk suhu dan satu lagiuntuk keadaan cuaca keseluruhan.cd react-weather npm install npm run dev
Dalam bahagian butiran, kami ingin memaparkan kelembapan dan kelajuan angin berturut-turut, jadi setiap satu akan berada dalam elemen divnya.
import { useState } from 'react' import './App.css' function App() { return ( <> </> ) } export default App
Akhir sekali, bahagian ramalan akan mempunyai tajuk dan beberapa item senarai untuk setiap hari. Untuk item senarai, mari mulakan dengan memaparkan dua hari buat masa ini.
import { useState } from 'react' import './App.css' function App() { return ( <div className="wrapper"> </div> ) } export default App
Setakat ini, apl kami kini kelihatan seperti ini:
Untuk menjadikan antara muka kami cantik, mari tambah gaya, kami akan menggunakan CSS. Dalam fail main.jsx, kami sudah mempunyai import ini yang mengimport semua gaya global untuk apl kami
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;
Mari kita mulakan dengan menggayakan badan dengan menggunakan 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> ); }
Di sini, kami telah menetapkan justify-item:center dan justify-content:center untuk memastikan semua kandungan dipusatkan secara mendatar dan menegak.
Untuk pembalut, mari tambahkan warna latar belakang yang berbeza, lebar min, jejari sempadan dan bayang kotak, dan juga jidar pada semua sisi.
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> ); }
Tambahkan saiz fon yang lebih besar pada nama bandar dan elemen suhu dan menjadikannya tebal. Gaya keseluruhan untuk elemen pengepala akan kelihatan seperti ini:
import './index.css'
Untuk memastikan elemen dalam bahagian butiran cuaca (iaitu, kelembapan dan kelajuan angin) dijajarkan pada baris yang sama, gunakan paparan: flex dan justify-kandungan: ruang-antara; Ini ialah gaya untuk butiran cuaca dan elemennya:
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; }
Akhir sekali, untuk bahagian ramalan cuaca, tambah gaya berikut:
.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); }
Kini Apl kami kelihatan seperti ini:
Setakat ini kami menggunakan data pemegang tempat, untuk mendapatkan maklumat cuaca masa nyata, kami akan menggunakan API openweather. Pergi ke https://openweathermap.org/api dan dapatkan kunci API PERCUMA.
Tentukan API_KEY.
.city { font-size: 2.5rem; font-weight: bold; } .temperature { font-size: 3.5rem; font-weight: bold; } .condition { font-size: 1.25rem; }
Dalam persekitaran pengeluaran, anda harus menambahkan data sensitif seperti kunci API dalam fail .env.
Dalam React, state ialah konsep yang penting kerana ia membenarkan komponen mengurus dan bertindak balas kepada data dinamik. Apabila anda mengambil data daripada API, anda memerlukan cara untuk menyimpan dan memanipulasi data tersebut dalam komponen anda.
Di sinilah wujudnya negeri.
Semua dalam komponen React yang boleh berubah dari semasa ke semasa diuruskan oleh kerajaan. Apabila keadaan berubah, komponen React akan memaparkan semula dan mencerminkan perubahan baharu.
Sebagai contoh, dalam apl cuaca kami, kami ingin mendapatkan maklumat cuaca semasa untuk bandar tertentu dan menyimpannya di negeri itu.
Untuk melakukan itu, kami akan menggunakan cangkuk useState. Sintaks untuk cangkuk ini kelihatan seperti ini:
npm create vite@latest react-weather
Tentukan keadaan data cuaca di bahagian atas fungsi Apl. Nilai awal akan menjadi batal
cd react-weather npm install npm run dev
Tentukan negeri untuk bandar dan tetapkan pembolehubah negeri awal nama bandar kepada London
import { useState } from 'react' import './App.css' function App() { return ( <> </> ) } export default App
Tindak balas secara lalai tidak mempunyai cara untuk mengendalikan kesan sampingan. Kesan sampingan ialah operasi yang berlaku di luar kawalan Reacts seperti operasi tak segerak, storan tempatan, e.t. c .
Memandangkan komponen React dipaparkan apabila ia dipasang, membuat permintaan API pada peringkat ini tidak akan mempunyai akses kepada data lagi kerana permintaan pengambilan mengambil masa untuk diselesaikan.
Dalam kes sedemikian, React menggunakan cangkuk useEffect untuk melakukan kesan sampingan. Cangkuk useEffect mengambil fungsi sebagai parameter pertama dan tatasusunan kebergantungan. Sintaksnya kelihatan seperti ini:
import { useState } from 'react' import './App.css' function App() { return ( <div className="wrapper"> </div> ) } export default App
Susun atur kebergantungan dalam cangkuk useEffect mengandungi pembolehubah yang menentukan bila kesan harus dijalankan. Contohnya, dalam kes kami, useEffect harus dijalankan apabila data cuaca berubah dan bukannya pada setiap paparan.
Di dalam useEffect, cipta fungsi tak segerak yang akan mengambil cuaca untuk bandar tertentu daripada Open weather API. Memandangkan ia adalah operasi tak segerak, fungsi kita juga seharusnya tak segerak.
Fungsi mengambil cityName sebagai parameter
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;
Setelah data diambil, gunakan fungsi setWeatherData untuk mengemas kini keadaan dengan data respons. Pastikan untuk membalut kod anda dalam blok cuba-tangkap untuk mengendalikan sebarang kemungkinan ralat.
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> ); }
Untuk data diambil pada pelekap, kita perlu menggunakan fungsi data cuaca ambil di dalam useEffect.
Apabila menggunakan fungsi, kami akan memberikan nilai bandar semasa sebagai hujah. Ini akan memastikan bahawa apabila apl dipasang buat kali pertama, kami sudah mempunyai beberapa data untuk ditunjukkan untuk nilai yang ditentukan di negeri bandar.
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> ); }
Jika anda menyemak log dengan alatan pembangun anda, anda akan melihat bahawa kami membuat berbilang permintaan API pada setiap paparan.
Ini adalah operasi yang sangat mahal, untuk mengelakkan pengambilan pada setiap pemaparan, kami perlu menyediakan beberapa kebergantungan kepada useEffect. Kebergantungan ini akan menentukan apabila panggilan API dibuat ke API cuaca terbuka.
Jadi mari tambah bandar dalam tatasusunan kebergantungan untuk memastikan panggilan API hanya akan dibuat pada lekapan pertama atau apabila nilai bandar berubah.
npm create vite@latest react-weather
Apabila kami log data, kami mendapat objek yang mengandungi butiran cuaca untuk bandar London.
cd react-weather npm install npm run dev
Sekarang mari kita masukkan butiran cuaca ke dalam elemen menggunakan JSX.
import { useState } from 'react' import './App.css' function App() { return ( <> </> ) } export default App
Dalam JavaScript, syarat ungkapan && digunakan untuk pemaparan bersyarat dalam komponen React.
Pengendali && menyemak dua syarat dan mengembalikan benar hanya jika kedua-dua syarat adalah benar. Dalam kes kami, jika weatherDataexist, sifat data yang ditentukan akan dipaparkan.
Jika weatherData adalah null (atau undefined), elemen tidak akan dipaparkan, menghalang sebarang ralat yang boleh berlaku daripada cuba mengakses sifat null.
Untuk mendapatkan ramalan, kami akan melakukan permintaan pengambilan lain dalam useEffect Hook yang sama menggunakan API ini https://api.openweathermap.org/data/2.5/forecast?q=${CITY}&appid=${API_KEY} &unit=imperial
Mula-mula, buat keadaan ramalan untuk menyimpan data ramalan dan mulakan nilai awal kepada tatasusunan kosong.
import { useState } from 'react' import './App.css' function App() { return ( <div className="wrapper"> </div> ) } export default App
Di dalam fungsi fetchWeatherData, buat permintaan pengambilan kepada API di atas dan tetapkan keadaan ramalan kepada data respons.
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 ramalan biasanya mengembalikan ramalan selepas setiap 3 jam untuk 5 hari seterusnya, menghasilkan 40 titik data, berikut ialah output yang dipotong.
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> ); }
Pembolehubah dt ialah cap masa, jadi jika kita mahu menukarnya kepada masa yang boleh dibaca manusia menggunakan kaedah 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> ); }
Output untuk cap masa ini telah ditetapkan
Jadi untuk tatasusunan 40 item ramalan, kami telah menggunakan fungsi penapis untuk menapis berdasarkan (item, indeks) => indeks % 8 === 0syarat.
(item, indeks) => indeks % 8 === 0: Keadaan ini bermaksud: "Hanya simpan ramalan di mana indeks boleh dibahagikan dengan 8." Memandangkan ramalan adalah setiap 3 jam, setiap item ke-8 mewakili satu ramalan setiap hari (3 jam × 8 = 24 jam).
Jadi sebagai contoh, memandangkan indeks berjulat dari 0–39, setiap indeks ke-8 ditambahkan pada tatasusunan DailyForecast. Secara keseluruhan, kami akan mempunyai 5 kejadian data cuaca.
Setiap titik data ramalan cuaca kelihatan seperti ini:
import './index.css'
Memandangkan kami mempunyai 5 kejadian, kami akan menggunakan kaedah map() untuk mengulang dan memaparkan ramalan untuk setiap hari.
Kemas kini bahagian ramalan seperti berikut:
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; }
Di sini, kami juga menyemak sama ada tatasusunan ramalan mengandungi data untuk memastikan kami tidak menggelung tatasusunan kosong yang akan menyebabkan ralat timbul.
Selepas menyemak data ramalan, kami memetakan tatasusunan ramalan dan menyuntik data berikut untuk setiap hari.
Kini Apl kami kelihatan seperti ini:
Apl kami kelihatan hebat, tetapi kami masih tidak dapat mengambil data dinamik. Mari tambahkan borang carian di bahagian atas untuk membolehkan pengguna mendapatkan maklumat tentang mana-mana bandar.
Tetapi pertama, kita memerlukan keadaan untuk medan input. Isytiharkan keadaan dengan rentetan kosong sebagai nilai awal.
npm create vite@latest react-weather
Buat borang, ikat input kepada keadaan searchInput dan tambahkan acara onChange yang akan mengemas kini nilai searchInput apabila pengguna menaip bandar baharu.
cd react-weather npm install npm run dev
Berikut ialah gaya untuk borang.
import { useState } from 'react' import './App.css' function App() { return ( <> </> ) } export default App
Memandangkan kami perlu menggunakan fungsi weatherData apabila borang diserahkan, kami akan mengalihkan definisi fungsi di luar cangkuk useEffect tetapi masih memanggilnya kerana apl perlu memaparkan beberapa data untuk nilai bandar awal apabila ia dipasang.
import { useState } from 'react' import './App.css' function App() { return ( <div className="wrapper"> </div> ) } export default App
Selepas pengguna mencari bandar dengan borang carian, kami perlu memanggil fungsi lain yang akan menggunakan fetchWeatherData dengan bandar baharu dan mengemas kini keadaan weatherData kepada maklumat cuaca untuk bandar baharu.
Tambah onSubmitevent pada borang dan rujuk fungsi seperti yang ditunjukkan di bawah.
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;
Apabila borang diserahkan, ia akan mengambil maklumat cuaca untuk bandar baharu.
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> ); }
Memandangkan fungsi fetchWeatherData sudah mengemas kini keadaan baharu keadaan weatherData dengan data baharu, kami hanya menggunakan fungsi dan menghantar nilai bandar baharu daripada pengguna (searchInput).
Apabila mengambil data daripada API, pelbagai isu boleh berlaku. Contohnya, dalam kes kami, API cuaca mungkin tidak berfungsi, atau kami mungkin mempunyai kunci API yang tidak sah, atau kami mungkin telah menghabiskan had API harian kami.
Dalam kes ini, kami perlu menambah mekanisme pengendalian ralat yang betul supaya pengguna tidak mengalami ralat pelayan.
Sebagai contoh, apabila apl dimuatkan buat kali pertama, tatasusunan ramalan akan kosong dan weatherData akan menjadi batal. Untuk memastikan pengalaman pengguna yang baik, mari tambahkan ralat dan keadaan pemuatan.
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> ); }
Dalam fungsi fetchWeatherData, sejurus sebelum sebarang pengambilan berlaku, tetapkan keadaan awal ralat dan pemuatan
import './index.css'
Dalam blok tangkapan, mari tetapkan keadaan ralat kepada mesej mesra pengguna
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; }
Dalam JavaScript, klausa akhirnya dalam blok tangkap cuba bagus untuk membersihkan. Tanpa mengira hasil operasi API, kami ingin mengalih keluar keadaan pemuatan.
.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); }
Untuk memastikan ralat dan keadaan pemuatan ditunjukkan dalam UI, tambahkan kod ini sejurus sebelum pernyataan pemulangan
npm create vite@latest react-weather
Untuk memaparkan mesej ralat jika ia berlaku tambahkan
tag selepas borang.cd react-weather npm install npm run dev
Syarat ini memastikan bahawa jika ralat berlaku, mesej ralat yang disimpan dalam keadaan akan dipaparkan.
Berikut ialah apl dalam keadaan memuatkan.
Berikut ialah output apabila ralat berlaku.
Kami telah sampai ke penghujung tutorial ini. Anda boleh mencari kod sumber di sini.
Jika anda mendapati tutorial ini agak mencabar, anda mungkin perlu mempelajari Asas React anda.
Dapatkan Panduan React Percuma saya dan Naikkan Tahap.
Selamat Pengekodan.
Atas ialah kandungan terperinci Cara Membina Apl Cuaca dalam React. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!