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

如何修复React刷新时先显有序项再显随机20项的代码问题

解决刷新页面先显示原顺序再切换随机项的问题

问题出在你把数组打乱逻辑放在了useEffect中——useEffect是组件挂载完成后才执行的,所以第一次渲染时用的是未打乱的原数组,等useEffect执行完修改数组后,组件才会重新渲染显示随机项,这就导致了闪屏现象。

修改方案

情况1:Myjson是本地静态数据

直接在useState的初始化函数中完成数组打乱和截取,这样组件第一次渲染时就会使用处理好的随机数组:

import { useState } from 'react';

// 组件内部
const [randomItems, setRandomItems] = useState(() => {
  // 先复制原数组,避免修改原Myjson(防止影响其他使用该数组的逻辑)
  const copiedArr = [...Myjson];
  
  // Fisher-Yates 洗牌算法(修正了原代码的随机范围问题)
  for (let i = copiedArr.length - 1; i >= 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [copiedArr[i], copiedArr[j]] = [copiedArr[j], copiedArr[i]];
  }
  
  // 截取前20个随机项
  return copiedArr.slice(0, 20);
});

// 渲染部分直接用处理好的randomItems
{randomItems.map((item) => (
  <Link
    href={item.ud}
    key={item.id}
  >
    {item.test}
  </Link>
))}

情况2:Myjson是动态获取的(比如props、API请求返回)

如果Myjson是动态变化的,就需要在useEffect中监听Myjson的变化,重新生成随机数组,同时可以加个加载状态避免空内容:

import { useState, useEffect } from 'react';

// 组件内部
const [randomItems, setRandomItems] = useState([]);

useEffect(() => {
  if (!Myjson || Myjson.length === 0) return;
  
  const copiedArr = [...Myjson];
  for (let i = copiedArr.length - 1; i >= 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [copiedArr[i], copiedArr[j]] = [copiedArr[j], copiedArr[i]];
  }
  
  setRandomItems(copiedArr.slice(0, 20));
}, [Myjson]);

// 渲染时判断状态,避免未加载时显示空
{randomItems.length > 0 ? (
  randomItems.map((item) => (
    <Link
      href={item.ud}
      key={item.id}
    >
      {item.test}
    </Link>
  ))
) : (
  <div>加载中...</div>
)}

关键注意事项

  • 永远不要直接修改原数组(比如原代码直接操作a = Myjson后打乱),一定要先浅拷贝([...Myjson]),否则会污染原数据,引发其他逻辑问题。
  • 原代码的洗牌算法有个小问题:Math.random() * i生成的随机数范围是0 ≤ j < i,会导致最后一个元素永远不会和自己交换,修正为Math.random() * (i + 1)才能覆盖所有索引。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 23:30:19