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

如何优化实现随机图展示、点击切换功能的React小代码?

React随机图片组件优化方案

现存问题

  • 定义的imagenactual状态完全未被使用,当前图片地址imagenaleatoria是每次组件渲染时随机生成的,会导致任何触发组件重渲染的操作都会自动切换图片,不符合「仅点击切换」的需求
  • 随机下标计算从1开始,会遗漏数组下标为0的第一张图片,且随机逻辑多处重复书写冗余
  • 未处理接口请求中的加载状态,接口返回前gifs是空数组,gifs.length为0会导致取值为undefined,控制台报错
  • 工具函数、常量定义在组件内部,每次渲染都会重复创建,性能浪费
  • 图片没有加alt属性,不符合可访问性规范

优化后代码

import React, { useEffect, useState, useCallback } from 'react';
// 常量、工具函数移到组件外,避免重复创建
const API_URL = 'https://picsum.photos/v2/list?page=2&limit=100';
// 封装通用随机数函数,返回[min, max)区间的整数
const getRandomInt = (min, max) => {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min;
};

export default function RandomImage() {
  const [imageList, setImageList] = useState([]);
  // 直接用一个状态存当前展示的图片地址,就是你原来的第二个useState的正确用法
  const [currentImage, setCurrentImage] = useState('');
  // 加载状态避免空数组报错
  const [isLoading, setIsLoading] = useState(true);

  // 封装切换随机图片的逻辑,避免重复代码
  const changeRandomImage = useCallback(() => {
    if (imageList.length < 2) return;
    let newIndex;
    // 避免连续两次抽到同一张图
    do {
      newIndex = getRandomInt(0, imageList.length);
    } while (imageList[newIndex] === currentImage);
    setCurrentImage(imageList[newIndex]);
  }, [imageList, currentImage]);

  useEffect(() => {
    fetch(API_URL)
      .then(res => res.json())
      .then(response => {
        const urls = response.map(image => image.download_url);
        setImageList(urls);
        // 请求成功后初始化第一张随机图
        const firstIndex = getRandomInt(0, urls.length);
        setCurrentImage(urls[firstIndex]);
      })
      .finally(() => setIsLoading(false));
  }, []);

  if (isLoading) return <div>图片加载中...</div>;

  return (
    <div className='App'>
      <section className='App-header'>
        <div className='caja'>
          <img
            onClick={changeRandomImage}
            src={currentImage}
            alt="随机展示图片"
            style={{ cursor: 'pointer' }}
          />
        </div>
      </section>
    </div>
  );
}

核心优化说明

  • 原来的第二个useState是正确的设计方向,你之前的问题只是没有把它绑定到img的src属性上,优化后直接用这个状态存储当前展示的图片地址,所有切换逻辑都围绕这个状态操作,不会出现非预期的自动换图问题
  • 封装了通用的随机逻辑和切换图片方法,消除重复代码,同时新增了避免连续两次展示同一张图的逻辑,体验更好
  • 新增加载状态,解决请求返回前空数组取值报错的问题
  • 把不需要随组件渲染更新的常量、工具函数移到组件外部,changeRandomImage用useCallback缓存,减少不必要的重复创建

内容的提问来源于stack exchange,提问作者wilfy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 05:18:02