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

基于React State映射数组异常:切换按钮变更未触发重渲染

问题原因

你定义的toOrderState状态仅在组件首次渲染时根据showLateJobs的初始值完成初始化,后续切换按钮修改showLateJobs时,toOrderState不会自动重新计算更新,所以列表内容不会跟着变化。

解决方案

方案一:用useMemo推导计算值(推荐)

既然toOrderState是基于showLateJobs、user等状态推导出来的结果,不需要单独存为state,直接用useMemo缓存计算逻辑,依赖变化时自动更新:

import { useState, useMemo } from 'react';

const App = () => {
  const [showLateJobs, setShowLateJobs] = useState(true);
  const [user, setUser] = useState("default");
  const multipleUsersArray = [...otherUser, ...AllJobs];

  // 用useMemo缓存计算结果,依赖变化时自动重新计算
  const toOrderState = useMemo(() => {
    const baseArray = user === "default" ? AllJobs : multipleUsersArray;
    return baseArray.filter(job => {
      if (job.category !== "to_order") return false;
      // 控制是否显示逾期任务
      return showLateJobs ? true : !job.late;
    });
  }, [showLateJobs, user, AllJobs, otherUser]); // 所有依赖项都要放进数组

  return (
    <>
      <Toggle
        defaultChecked={true}
        onChange={(e) => {
          setShowLateJobs(e.target.checked); // 简化逻辑
        }}
      />

      <Column>
        {toOrderState.map((job) => (
          <JobCard
            key={job.jobNumber} // 用唯一标识当key,提升渲染性能
            job_number={job.jobNumber}
            time={job.time}
            cardHeight={layout === "extended" ? "150px" : "50px"}
            layout={layout}
            backgroundColor={job.late && "#D64045"}
            displayLateIcon={job.late && "block"}
          />
        ))}
      </Column>
    </>
  );
};

方案二:手动监听状态变化更新toOrderState

如果一定要保留toOrderState的state,可以用useEffect监听showLateJobs和user的变化,手动更新状态:

import { useState, useEffect } from 'react';

const App = () => {
  const [showLateJobs, setShowLateJobs] = useState(true);
  const [user, setUser] = useState("default");
  const [toOrderState, setToOrderState] = useState([]);
  const multipleUsersArray = [...otherUser, ...AllJobs];

  // 监听依赖变化,重新计算并更新状态
  useEffect(() => {
    let targetArray;
    if (user === "default") {
      targetArray = showLateJobs 
        ? AllJobs.filter(job => job.category === "to_order")
        : AllJobs.filter(job => job.category === "to_order" && !job.late);
    } else {
      targetArray = showLateJobs
        ? multipleUsersArray.filter(job => job.category === "to_order")
        : multipleUsersArray.filter(job => job.category === "to_order" && !job.late);
    }
    setToOrderState(targetArray);
  }, [showLateJobs, user, AllJobs, otherUser]);

  return (
    <>
      <Toggle
        defaultChecked={true}
        onChange={(e) => {
          setShowLateJobs(e.target.checked);
        }}
      />

      <Column>
        {toOrderState.map((job) => (
          <JobCard
            key={job.jobNumber} // 用唯一标识当key
            job_number={job.jobNumber}
            time={job.time}
            cardHeight={layout === "extended" ? "150px" : "50px"}
            layout={layout}
            backgroundColor={job.late && "#D64045"}
            displayLateIcon={job.late && "block"}
          />
        ))}
      </Column>
    </>
  );
};

额外优化点

  • 把job.late != true改成!job.late,逻辑更简洁规范
  • 给列表项加上key属性,优先用数据的唯一标识(比如job.jobNumber)而非索引,避免渲染异常
  • 简化Toggle的onChange逻辑,直接通过e.target.checked赋值给showLateJobs

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 09:35:21