React应用中动态修改NASA APOD API请求URL日期的方法
Hey Mike, great question! Displaying the last 4 days of APOD is a perfect use case for combining date manipulation with parallel API requests in React. Let's break this down step by step.
First, we need a helper function to create an array of dates formatted as YYYY-MM-DD (the format the NASA API expects). This function will grab today's date and subtract 0, 1, 2, and 3 days to get the past 4 days.
const getLastFourDates = () => { const dates = []; const today = new Date(); // Loop 4 times to capture today + previous 3 days for (let i = 0; i < 4; i++) { const date = new Date(today); date.setDate(today.getDate() - i); // Convert to ISO string and slice off the time portion const formattedDate = date.toISOString().split('T')[0]; dates.push(formattedDate); } return dates; };
Next, we'll build a component that uses this date array to fetch data for each day, then renders the results. We'll use useState to manage our data, loading state, and errors, plus useEffect to trigger the API calls when the component mounts.
We'll use Promise.all to fetch all 4 APODs in parallel (faster than sequential requests!) and handle both images and videos since APOD occasionally returns video content.
import { useState, useEffect } from 'react'; const APODGallery = () => { const [apodData, setApodData] = useState([]); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); const API_KEY = 'DEMO_KEY'; // Replace this with your own NASA API key! const BASE_URL = 'https://api.nasa.gov/planetary/apod'; useEffect(() => { const fetchAPODs = async () => { try { setIsLoading(true); const targetDates = getLastFourDates(); // Create an array of fetch promises for each date const fetchPromises = targetDates.map(date => { const requestUrl = `${BASE_URL}?api_key=${API_KEY}&date=${date}`; return fetch(requestUrl).then(response => { if (!response.ok) throw new Error(`Failed to load APOD for ${date}`); return response.json(); }); }); // Wait for all requests to complete const galleryData = await Promise.all(fetchPromises); setApodData(galleryData); setError(null); } catch (err) { setError(err.message); setApodData([]); } finally { setIsLoading(false); } }; fetchAPODs(); }, []); // Empty dependency array ensures this runs once on component mount // Handle loading and error states first if (isLoading) return <div>Loading your daily astronomy pics...</div>; if (error) return <div>Oops, something went wrong: {error}</div>; // Render the gallery return ( <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '2rem', padding: '2rem' }}> {apodData.map((apod, index) => ( <div key={index} style={{ border: '1px solid #eee', padding: '1rem', borderRadius: '8px' }}> <h3>{apod.title} ({apod.date})</h3> {apod.media_type === 'image' ? ( <img src={apod.url} alt={apod.title} style={{ width: '100%', height: '250px', objectFit: 'cover', borderRadius: '4px' }} /> ) : ( <iframe src={apod.url} title={apod.title} style={{ width: '100%', height: '250px', border: 'none', borderRadius: '4px' }} /> )} <p style={{ marginTop: '1rem', fontSize: '0.9rem' }}>{apod.explanation.slice(0, 150)}...</p> </div> ))} </div> ); }; // Include our date helper function here const getLastFourDates = () => { const dates = []; const today = new Date(); for (let i = 0; i < 4; i++) { const date = new Date(today); date.setDate(today.getDate() - i); const formattedDate = date.toISOString().split('T')[0]; dates.push(formattedDate); } return dates; }; export default APODGallery;
- API Key Limits: The
DEMO_KEYonly allows 30 requests per hour and 50 per day. For regular use, grab a free key from NASA's API portal to get higher limits. - Error Handling: The code includes basic error catching for failed requests—you can expand this to retry failed calls if needed.
- Responsive Layout: The inline styles make the gallery responsive out of the box, but you can swap them for your own CSS classes.
内容的提问来源于stack exchange,提问作者Mike G

