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

ReactJS如何实现每秒一次循环?排序算法可视化步骤展示异常

问题分析与修复方案

你的代码存在几个核心问题导致无法看到排序过程:

  1. 直接修改State数组且未触发重渲染:你直接修改了arr的元素(arr[i] = arr[minIndex]),但React的State必须通过setArr更新才能触发组件重渲染,否则页面不会同步变化。
  2. 错误的循环与useEffect使用:useEffect不能放在while循环或条件语句中,违反React的Hook规则;同时arr.sort()会原地修改原数组,导致页面加载时数组就被直接排序,while (arr != arr.sort())的条件永远不成立(因为arr.sort()返回原数组引用),循环根本不会执行。
  3. SetTimeout闭包问题:for循环中直接使用setTimeout会导致所有定时器共享同一个i变量,最终执行时i已经是循环的最后一个值,逻辑完全错误;且循环会一次性创建所有定时器,导致所有排序步骤几乎同时完成,看不到间隔效果。

修复后的代码

import React, { useState, useEffect } from 'react'

const SortingAlgorithm: React.FC = () => {
  const [arr, setArr] = useState<number[]>([3, 1, 2, 5, 4]);

  useEffect(() => {
    // 复制原数组,避免修改state原始值
    const array = [...arr];
    let i = 0;

    const performSelectionSortStep = () => {
      if (i >= array.length - 1) return; // 排序完成,终止

      let minIndex = i;
      // 找到当前未排序部分的最小值索引
      for (let j = i + 1; j < array.length; j++) {
        if (array[j] < array[minIndex]) {
          minIndex = j;
        }
      }

      // 交换元素,生成新数组
      const newArray = [...array];
      [newArray[i], newArray[minIndex]] = [newArray[minIndex], newArray[i]];
      setArr(newArray);
      i++;

      // 1秒后执行下一步
      setTimeout(performSelectionSortStep, 1000);
    };

    // 启动排序流程
    const timer = setTimeout(performSelectionSortStep, 1000);

    // 组件卸载时清除定时器
    return () => clearTimeout(timer);
  }, []);

  return (
    <div style={{ display: 'flex', gap: '8px', alignItems: 'flex-end', height: '300px', padding: '20px' }}>
      {arr.map((value, index) => (
        <div key={index} style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
          <svg height="250" width="40">
            <rect 
              height={value * 50} 
              width="35" 
              y={250 - value * 50} 
              fill="#4299e1"
            />
          </svg>
          <span>{value}</span>
        </div>
      ))}
    </div>
  )
}

export default SortingAlgorithm;

关键修改说明

  • 用递归定时器控制步骤:通过performSelectionSortStep函数递归调用,每次执行完一步排序后,1秒后触发下一步,确保每一步都有可见的间隔。
  • Immutable更新State:每次排序步骤都生成新数组([...array]),通过setArr更新,触发组件重渲染,展示最新的数组状态。
  • 避免原地修改数组:始终操作数组的副本,防止意外修改State原始值。
  • 正确的useEffect使用:在组件挂载时启动排序流程,符合React Hook规则,且组件卸载时清除定时器,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 07:07:06