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

React中如何让shuffle函数仅在页面重载时执行?

解决React中Shuffle函数仅在页面重载时执行的问题

你的核心问题是:每次组件重渲染(比如点击按钮修改display状态)时,都会重新创建数组并执行shuffle,导致数组反复被打乱。要让shuffle只在组件首次挂载(页面重载)时执行一次,你需要通过useState维护数组状态,并用useEffect控制shuffle的执行时机。

问题根源

  1. 组件每次渲染时,let array = [...]都会重新生成一个新数组,紧接着调用shuffle(array),所以每次重渲染都会打乱数组。
  2. 直接在组件顶层执行shuffle,没有限制执行时机,导致状态更新时重复执行。

修改方案

  1. 将原始数组定义在组件外部(或者用useMemo缓存),避免每次渲染重新创建。
  2. 使用useState存储打乱后的数组,初始值可以设为原始数组。
  3. 通过useEffect(依赖项为空数组)在组件首次挂载时执行一次shuffle,并更新数组状态。
  4. 让shuffle函数操作数组的副本,避免修改原始数组(更安全的做法)。

修改后的完整代码

import { useEffect, useState } from "react";
import audi from "./images/audi.jpg";
import blackcar from "./images/carinblack.jpg";
import ferrari from "./images/ferrari.jpg";
import lambo from "./images/lambo.jpg";
import rangerover from "./images/rangerover.jpg";

// 原始数组放在组件外部,避免每次渲染重新创建
const originalArray = [audi, blackcar, ferrari, lambo, rangerover, audi];

export const Robot = () => {
  const [display, setDisplay] = useState('none');
  // 用state存储打乱后的数组,初始值为原始数组
  const [shuffledArray, setShuffledArray] = useState(originalArray);

  function shuffle(array) {
    // 先拷贝数组,避免修改原始数组
    const newArray = [...array];
    let currentIndex = newArray.length, randomIndex;

    while (currentIndex !== 0) {
      randomIndex = Math.floor(Math.random() * currentIndex);
      currentIndex--;
      [newArray[currentIndex], newArray[randomIndex]] = [newArray[randomIndex], newArray[currentIndex]];
    }

    return newArray;
  }

  // 空依赖项的useEffect仅在组件首次挂载时执行一次
  useEffect(() => {
    const result = shuffle(originalArray);
    setShuffledArray(result);
  }, []); // 依赖项为空,只执行一次

  const handle = () => {
    setDisplay('inline');
  };

  const Reset = () => {
    setDisplay('none');
  };

  return (
    <>
      {shuffledArray.map((data, index) => (
        <img key={index} onClick={handle} src={data} />
      ))}
      <h3>
        Please click on the identical tiles to verify that you are not a robot
      </h3>
      <button id='reset' style={{display: display}} onClick={Reset}>Reset</button>
    </>
  );
};

关键改动说明

  • 把originalArray移到组件外部,确保每次渲染不会重新创建数组。
  • 用shuffledArray状态存储打乱后的结果,组件渲染时依赖这个状态,不会因为重渲染重新打乱。
  • useEffect的依赖项设为[],确保shuffle只在组件首次挂载时执行一次,对应页面重载的场景。
  • shuffle函数中先拷贝数组,避免修改原始数组,保证每次打乱的都是原始数组的副本。
  • 给img元素添加key属性,符合React列表渲染的要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 11:45:32