You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 07:18:02