React从Unsplash拉取图片时setImages触发Hook错误求助
问题原因及修复方案
核心错误点
- 陈旧闭包导致状态更新异常:你的
fetchImages函数在组件首次渲染时创建,捕获的images永远是初始空数组,直接用setImages([...images, ...res.data])会每次基于旧状态覆盖更新,触发Hook相关报错。解决方案是使用状态更新的函数式写法,每次基于最新的前序状态做合并。 - Unsplash API请求参数错误:你的请求路径中
{clientid}没有正确使用模板字符串语法,也没有替换为你自己在Unsplash开发者平台申请的Client ID,会导致请求鉴权失败。 - 无限滚动组件未启用:已导入的
react-infinite-scroll-component没有实际用到,无法触发滚动加载逻辑。 - 子组件key属性使用错误:React的
key是保留属性,不需要作为子组件的props接收和传递,多余的声明可以删除。
修正后的代码
Landing组件
import React, { useState, useEffect } from 'react'; import axios from 'axios'; import { UnsplashImage } from './randomImages/UnsplashImage'; import InfiniteScroll from 'react-infinite-scroll-component'; const Landing = () => { const [images, setImages] = useState([]); // 新增:控制是否还有更多内容可以加载 const [hasMore, setHasMore] = useState(true); useEffect(() => { fetchImages(); }, []) const fetchImages = async (count = 10) => { const apiRoot = "https://api.unsplash.com"; // 替换成你自己的Unsplash Client ID const CLIENT_ID = "你自己申请的Unsplash Client ID"; try { const res = await axios.get(`${apiRoot}/photos/random?client_id=${CLIENT_ID}&count=${count}`); // 使用函数式更新,基于最新的前序状态合并 setImages(prevImages => [...prevImages, ...res.data]); // 示例:如果返回数据少于请求数量,说明没有更多内容了,可以按需调整逻辑 if(res.data.length < count) { setHasMore(false); } } catch (err) { console.error("请求图片失败:", err); setHasMore(false); } }; return ( <div className="Landing"> <style>{ 'body {background-color: #5e90be}'}</style> <img id = "x" src= "example_images/logo.png" alt="logo"></img> <h5>Welcome to Photodex</h5> {/* 启用无限滚动组件 */} <InfiniteScroll dataLength={images.length} next={fetchImages} hasMore={hasMore} loader={<h4>加载中...</h4>} endMessage={<p>没有更多图片了</p>} > <div className="image-grid"> {images.map(image => ( <UnsplashImage url={image.urls.regular} key={image.id} alt={image.description || "Unsplash图片"} /> ))} </div> </InfiniteScroll> </div> ) } export default Landing;
UnsplashImage.js组件
import React from 'react'; import styled from 'styled-components'; const Img = styled.img` width: 100%; height: 100%; object-fit: cover; `; // 删除多余的key props export const UnsplashImage = ({ url, alt }) => { return ( <Img src={url} alt={alt} /> ) }
额外注意事项
记得先去Unsplash开发者平台注册应用,拿到属于你的Client ID替换到代码对应位置,否则请求会被拦截返回401错误。
内容的提问来源于stack exchange,提问作者Nick Ghuman
相关产品推荐
相关产品推荐

