React调用NASA随机图片API时详情页无法获取对应图片数据怎么办
问题根因
- 你对NASA APOD接口的使用逻辑有误,该接口携带
count参数时只会返回对应条数的随机内容,不支持title查询参数,你在详情页请求时依然携带count=6,返回的必然是全新的随机数据,无法匹配之前列表的内容。 - 用title作为路由唯一标识也存在风险,可能出现重复标题的APOD内容,官方推荐用
date参数作为唯一标识,APOD接口支持通过date参数精准查询指定日期的单条内容。
解决方案(推荐,详情页刷新也可用)
1. 修改路由配置(App.js)
将路由参数替换为date,保证唯一性:
import React from "react"; import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; import "./App.css"; import FeaturedProducts from "./FeaturedProducts"; import Product from "./Product"; function App() { return ( <Router> <div> <Switch> <Route exact path="/" component={FeaturedProducts} /> <Route exact path="/product/:date" component={Product} /> </Switch> </div> </Router> ); } export default App;
2. 修改列表页跳转逻辑(FeaturedProducts.jsx)
跳转时携带选中内容的date参数而非title:
import React, { useState, useEffect } from "react"; import { Link } from "react-router-dom"; import axios from "axios"; const FeaturedProducts = () => { const [products, setProducts] = useState([]); useEffect(() => { fetchProducts(); }, []); const fetchProducts = () => { axios .get( "https://api.nasa.gov/planetary/apod/?api_key=xxxxxxxxx&count=6&thumbs=True" ) .then((res) => { setProducts(res.data); }) .catch((err) => { console.log(err); }); }; return ( <div> {products.map((product) => ( <div key={product.date}> <p>{product.title}</p> <img src={product.url} alt={product.title} /> <Link to={`/product/${product.date}`}>View</Link> </div> ))} </div> ); }; export default FeaturedProducts;
3. 修改详情页请求逻辑(Product.jsx)
移除count参数,用date查询单条对应内容:
import React, { useState, useEffect } from "react"; import { Link } from "react-router-dom"; import axios from "axios"; const Product = ({ match }) => { const [data, setData] = useState(null); useEffect(() => { fetchProduct(); }, [match.params.date]); const fetchProduct = () => { axios .get( `https://api.nasa.gov/planetary/apod/?api_key=xxxxxxxxxx&thumbs=True&date=${match.params.date}` ) .then((res) => { setData(res.data); console.log(res.data); }) .catch((err) => console.log(err)); }; if (!data) return <div>加载中...</div> return ( <div> <div> <p>{data.title}</p> <p>日期:{data.date}</p> <img src={data.url} alt={data.title} /> <p>描述:{data.explanation}</p> </div> <div> <Link to="/">Back</Link> </div> </div> ); }; export default Product;
可选方案
如果你不想在详情页重复发请求,可以将列表接口返回的6条数据存在全局状态(如React Context、Redux)或LocalStorage中,详情页直接根据date匹配对应数据即可,无需二次请求。该方案的缺点是用户直接访问详情页、或刷新详情页时如果存储的数据丢失会导致页面异常。
内容的提问来源于stack exchange,提问作者user16888326
相关产品推荐
相关产品推荐

