React中如何让shuffle函数仅在页面重载时执行?
解决React中Shuffle函数仅在页面重载时执行的问题
你的核心问题是:每次组件重渲染(比如点击按钮修改display状态)时,都会重新创建数组并执行shuffle,导致数组反复被打乱。要让shuffle只在组件首次挂载(页面重载)时执行一次,你需要通过useState维护数组状态,并用useEffect控制shuffle的执行时机。
问题根源
- 组件每次渲染时,
let array = [...]都会重新生成一个新数组,紧接着调用shuffle(array),所以每次重渲染都会打乱数组。 - 直接在组件顶层执行shuffle,没有限制执行时机,导致状态更新时重复执行。
修改方案
- 将原始数组定义在组件外部(或者用
useMemo缓存),避免每次渲染重新创建。 - 使用
useState存储打乱后的数组,初始值可以设为原始数组。 - 通过
useEffect(依赖项为空数组)在组件首次挂载时执行一次shuffle,并更新数组状态。 - 让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
相关产品推荐
相关产品推荐

