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

Antd Tabs标签页移除功能异常问题求助

解决Antd Tabs标签页移除异常问题

核心问题总结

  1. Tabs状态未正确绑定:仅使用defaultActiveKey初始化,未将activeKey状态与Tabs组件绑定,导致切换标签时状态未同步,删除操作无法关联正确目标。
  2. 删除逻辑错误:依赖未声明的全局变量key,且错误移除当前激活标签而非用户点击的目标标签。
  3. 初始化值无效:activeKey初始化引用未定义的initialItems,导致初始状态异常。

修复后的完整代码

import React, { useState, useEffect } from 'react';
import Image from "next/image";
import { Title, ButtonWrap } from '../../styles/com';
import { Dropdown, Card, Button, Divider, Tabs } from 'antd';
import { MoreOutlined, CheckOutlined } from '@ant-design/icons';
import ArtsInsertFormTab from './ArtsInsertFormTab';

export default function ArtsInsertTab(props) {
  const items = [
    {
      key: '1',
      label: 'delete'
    },
  ];

  // 生成标签项,为每个删除按钮绑定当前标签key
  const generateTabItems = () => {
    return props.imgList.map((_, i) => {
      const tabKey = String(i + 1);
      return {
        label: <Image alt="example" src={props.imgList[i].url} width='60' height='60'/>,
        key: tabKey,
        children: (
          <div>
            <Card
              data-props='collapse'
              bordered={false}
              extra={
                <>
                  <Dropdown menu={{
                    items,
                    onClick: () => remove(tabKey)
                  }}>
                    <a onClick={(e) => e.preventDefault()}>
                      <MoreOutlined/>
                    </a>
                  </Dropdown>
                </>
              }>
              <ArtsInsertFormTab props={props.imgList[i]}/>
            </Card>
            <ButtonWrap>
              <Button onClick={cancleButton} size='large'><div>cancle</div></Button>
              <div>
                <Button size='large'><div>dd</div></Button>
                <Button type='primary' size='large' onClick={saveButton} icon={<CheckOutlined/>}><div>save</div></Button>
              </div>
            </ButtonWrap>
          </div>
        )
      };
    });
  };

  const venueId = props.venueId;
  const formData = new FormData();
  // 初始化activeKey为第一个标签的key
  const [activeKey, setActiveKey] = useState(props.imgList.length > 0 ? String(1) : '');
  const [tabitems, setTabItems] = useState(generateTabItems());
  const [isCheckUse, setIsCheckUse] = useState(false);
  const [formState, setFormState] = useState({
    artwork_title: "",
    artwork_artist_nm: "",
    artwork_date: "",
    artwork_img_alt: "",
    artwork_meterial: "",
    artwork_size: "",
    mapping_list: "",
    artwork_location: "",
    artwork_intro_url: "",
    artwork_view_url: "",
    artwork_view_playtime: "",
    artwork_next: "",
    artwork_tag1: "",
    artwork_tag2: "",
    artwork_tag3: "",
    artwork_tag4: "",
    use_yn: "",
  });

  useEffect(() => {
    console.log("tabtimeslend: " + tabitems.length);
  }, [tabitems]);

  // 监听props.imgList变化,同步更新标签项
  useEffect(() => {
    setTabItems(generateTabItems());
    if (props.imgList.length > 0) {
      setActiveKey(String(1));
    }
  }, [props.imgList]);

  const cancleButton = () => {};

  const saveButton = () => {
    formData.append("exhibition_nm", formState.exhibition_nm);
    formData.append("exhibition_start_date", formState.exhibition_start_date);
    formData.append("exhibition_end_date", formState.exhibition_end_date);
    formData.append("exhibition_inline_text", formState.exhibition_inline_text);
    formData.append("exhibition_img_alt", formState.exhibition_img_alt);
    formData.append("exhibition_text", formState.exhibition_text);
    formData.append("multipartFiles_map", formState.multipartFiles_map);
    formData.append("exhibition_intro_url", formState.exhibition_intro_url);
    formData.append("exhibition_img_ext", props.imgList[0].ext);
    formData.append("exhibition_img_type", 'testImage');
    formData.append("multipartFiles_img", new Blob([JSON.stringify(props.imgList[0])], { type: "multipart/form-data" }));
    formData.append("exhibitionMapImgCnt", 1);
    formData.append("useyn", isCheckUse ? 'Y' : 'N');

    fetch(`http://localhost:8090/api/exhibition/insertExhibition`, {
      method: 'POST',
      body: formData,
      processData: false,
      contentType: false,
      headers: {}
    })
    .then(response => response.json())
    .then(response => {
      alert('accepte');
    });
  };

  const ontabChange = (newActiveKey) => {
    setActiveKey(newActiveKey); // 同步更新activeKey状态
  };

  const remove = (targetKey) => {
    let newActiveKey = activeKey;
    let newPanes = tabitems.filter(item => item.key !== targetKey);

    // 如果删除的是当前激活标签,自动切换到前一个或第一个标签
    if (newActiveKey === targetKey) {
      const targetIndex = tabitems.findIndex(item => item.key === targetKey);
      newActiveKey = targetIndex > 0 ? tabitems[targetIndex - 1].key : newPanes[0]?.key || '';
    }

    setTabItems(newPanes);
    setActiveKey(newActiveKey);
  };

  return (
    <>
      <Title>
        <h1>test</h1>
      </Title>
      <Tabs
        style={{minWidth: '1400px'}}
        activeKey={activeKey} // 绑定activeKey状态
        onChange={ontabChange}
        type="card"
        tabPosition="right"
        items={tabitems}
      />
    </>
  )
}

关键修复说明

  • 绑定Tabs状态:将activeKey通过activeKey属性传递给Tabs组件,确保切换和删除操作时状态同步。
  • 绑定目标标签key:生成标签项时将当前标签的key传入删除函数,精准删除用户点击的标签。
  • 修正删除逻辑:判断删除的是否为当前激活标签,自动切换到合理的新激活标签,避免无激活标签的异常。
  • 修复初始化逻辑:根据props.imgList初始化activeKey,避免引用未定义变量。
  • 监听props变化:当props.imgList更新时自动同步标签项,保证数据一致性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 00:40:19