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

React中使用useState Hook更新对象数组isActive状态的问题

问题解决方法

原代码存在的几个关键错误:

  • 事件绑定错误:onClick={handleChange(opt,index)}会导致组件渲染时立即执行函数,而非点击触发,需要改成箭头函数包裹。
  • State更新逻辑错误:直接修改数组元素的写法不符合React不可变更新原则,且语法错误。
  • Map渲染未返回元素:options.map的回调函数没有return卡片组件,导致无法渲染。
  • State变量名不一致:定义了setOptions却使用setOption更新,存在拼写错误。

修正后的完整代码:

import { useState } from 'react';
import { Card, CardContent, Typography, Stack } from '@mui/material';
import FcApprove from 'react-icons/fc';
import FaHandsHelping from 'react-icons/fa';
import FaPrayingHands from 'react-icons/fa';

function FixedHeader() {
  // 直接在useState中初始化选项数组
  const [options, setOptions] = useState([
    {
      id: 1,
      label: "Borrowers",
      icon: FcApprove,
      counter: 2,
      link: "borrowers",
      color: "#5d8c6d",
      isActive: false,
    },
    {
      id: 2,
      label: "My Offer",
      icon: FaHandsHelping,
      counter: 2,
      link: "offer",
      color: "#04738a",
      isActive: false,
    },
    {
      id: 3,
      label: "Promise",
      icon: FaPrayingHands,
      counter: 2,
      link: "promise",
      color: "#40437a",
      isActive: false,
    }
  ]);

  const handleChange = (targetId) => {
    // 遵循React不可变更新原则,生成新数组
    setOptions(prevOptions => 
      prevOptions.map(opt => ({
        ...opt,
        // 点击项设为true,其余设为false(单选逻辑)
        isActive: opt.id === targetId
      }))
    );
  };

  return (
    <>
      {options.map((opt) => (
        <Card 
          onClick={() => handleChange(opt.id)} 
          key={opt.id} 
          className={opt.isActive ? "activecard" : ""}
        >
          <CardContent>
            <Stack direction="column">
              {/* 正确渲染图标组件 */}
              <opt.icon size={20} />
              {/* 正确插入变量 */}
              <Typography>{opt.label}</Typography>
            </Stack>
          </CardContent>
        </Card>
      ))}
    </>
  );
}

export default FixedHeader;

关键修正点说明:

  1. 事件绑定:用() => handleChange(opt.id)包裹,确保点击时才执行函数,同时传递当前项的id作为标识(比index更可靠,避免数组顺序变化导致的错误)。
  2. State更新:使用函数式更新setOptions(prevOptions => ...),基于前一次的state生成新数组,每个对象展开后修改isActive字段,确保只有点击项为true,其余为false(如果需要多选,只需把isActive: opt.id === targetId改成isActive: opt.id === targetId ? !opt.isActive : opt.isActive)。
  3. Map渲染:确保map回调返回Card组件,同时用opt.id作为key(比index更稳定)。
  4. 变量插入:修正Typography中的opt.label写法,去掉引号,正确插入变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 09:45:29