当前位置: 首页 > 知识库问答 >
问题:

react.js - React中Ant Design的Tabs组件如何使用items属性动态配置Tab,并在过滤时重置子组件数据?

鲍永春
2024-06-19

react中使用antd的Tabs,目前用的antd是5.17.0,因为这个版本的Tabs只能使用items来配置Tab,之前4.x.x的版本是用的TabPane。下面是Tabs的items,children是对应子组件。现在是通过useState对detailTabList里面的对象进行隐藏,根据其他的值来设置visiable,然后用filte过滤那些Tab不显示。因为这个导致children子组件{oDat}对象的值不会变(对象有多个属性),oDat也是放在useState中,有什么办法在过滤detailTabList时,重新设置children中oDat的值吗?

let detailTabList = [    {      label: 'test1',      key: '0',      visiable: true,      children: <RequestInfo oDat={oDat} iAppMod={state.type} ChangeRequestInfo={(v: any) => changeODat(v)}/>,    },    {      label: 'test2',      key: '1',      visiable: true,      children: <ResponseInfo oDat={oDat} iAppMod={state.type} ChangeResponseInfo={(v: any) => changeODat(v)}/>,    },    {      label: 'test3',      key: '2',      visiable: true,      children: <BureauManageInfo oDat={oDat} iAppMod={state.type} ChangeBureauManageInfo={(v: any) => changeODat(v)}/>,    }  ];

目前是用下面的方法。tabComList只存了key、children

setEditTabs((prev) => (prev.map(item => {          let tempVisible = item.visiable;          if (item.key == "4" || item.key == "5") {            tempVisible = false;          }          if (dataVForm.RadioSendKbn ==  dataVForm.radioRadioSendKbn && item.key == "6") {            // tab页隐藏            tempVisible = false;          }          let newChildren = tabComList.find(it => it.key == item.key)?.children;          return {...item, visiable: tempVisible, children: newChildren!};        }).filter(it => it.visiable == true)      ));

共有2个答案

云建木
2024-06-19

试了一下没有你说的问题,我觉得可能是对state的理解有差异。另一个可能是你的子组件内部是不是用state保存了oDat导致的oDat更新无效。
我的测试代码如下:

export default () => {  const [visibles, setVisibles] = useState(["0", "2"]);  const [data, setData] = useState([1, 2]);  const items = [{    key: "0",    label: '0',    visible: visibles.includes("0"),    children: <>{JSON.stringify(data)}</>  }, {    key: "1",    label: '1',    visible: visibles.includes("1"),    children: <>{JSON.stringify(data)}</>  }, {    key: "2",    label: '2',    visible: visibles.includes("2"),    children: <>{JSON.stringify(data)}</>  }, {    key: "3",    label: '3',    visible: visibles.includes("3"),    children: <>{JSON.stringify(data)}</>  }];  return <>    <Button onClick={() => {      setVisibles(visibles[0] === "0" ? ["1", "3"] : ["0", "2"]);      setData(data[0] === 1 ? [3, 4] : [1, 2]);    }}>Test</Button>    <Tabs items={items.filter(item => item.visible)} />  </>}
哈烨熠
2024-06-19

初始化和管理 state
使用 useState 来管理 detailTabList,并使用 useEffect 在 oDat 更新时重新生成 detailTabList。

import React, { useState, useEffect } from 'react';import { Tabs } from 'antd';import RequestInfo from './RequestInfo';import ResponseInfo from './ResponseInfo';import BureauManageInfo from './BureauManageInfo';const { TabPane } = Tabs;const MyComponent = () => {  const [oDat, setODat] = useState(initialODat);  const [detailTabList, setDetailTabList] = useState([    {      label: 'test1',      key: '0',      visiable: true,      children: <RequestInfo oDat={oDat} iAppMod={state.type} ChangeRequestInfo={(v) => changeODat(v)} />,    },    {      label: 'test2',      key: '1',      visiable: true,      children: <ResponseInfo oDat={oDat} iAppMod={state.type} ChangeResponseInfo={(v) => changeODat(v)} />,    },    {      label: 'test3',      key: '2',      visiable: true,      children: <BureauManageInfo oDat={oDat} iAppMod={state.type} ChangeBureauManageInfo={(v) => changeODat(v)} />,    },  ]);  // 更新 oDat 的方法  const changeODat = (newODat) => {    setODat(newODat);  };  // 根据 oDat 更新 detailTabList  useEffect(() => {    setDetailTabList([      {        label: 'test1',        key: '0',        visiable: true,        children: <RequestInfo oDat={oDat} iAppMod={state.type} ChangeRequestInfo={(v) => changeODat(v)} />,      },      {        label: 'test2',        key: '1',        visiable: true,        children: <ResponseInfo oDat={oDat} iAppMod={state.type} ChangeResponseInfo={(v) => changeODat(v)} />,      },      {        label: 'test3',        key: '2',        visiable: true,        children: <BureauManageInfo oDat={oDat} iAppMod={state.type} ChangeBureauManageInfo={(v) => changeODat(v)} />,      },    ]);  }, [oDat, state.type]);  // 过滤和设置可见的 tab  const visibleTabs = detailTabList    .map((item) => {      let tempVisible = item.visiable;      if (item.key === '4' || item.key === '5') {        tempVisible = false;      }      if (dataVForm.RadioSendKbn === dataVForm.radioRadioSendKbn && item.key === '6') {        tempVisible = false;      }      return { ...item, visiable: tempVisible };    })    .filter((item) => item.visiable);  return (    <Tabs>      {visibleTabs.map((tab) => (        <Tabs.TabPane tab={tab.label} key={tab.key}>          {tab.children}        </Tabs.TabPane>      ))}    </Tabs>  );};export default MyComponent;
  1. 初始化 State:
  2. 更新oDat方法:
  3. 使用useEffect监听oDatstate.type的变化:
    每当oDatstate.type变化时,重新生成detailTabList,确保子组件接收到最新的oDat
  4. 过滤和设置可见的 Tabs:
    根据业务逻辑过滤掉不应该显示的 Tabs。只显示visiabletrue的 Tabs。
  5. 渲染 Tabs:
    使用、Tabs`组件渲染过滤后的 Tabs 列表。
 类似资料:
  • 问题内容: 因此,单击该按钮后,我可以通过该事件获得该按钮。但是,当我做一个过滤器时,它不会删除所说的按钮。 所以我在构造函数()中有我的数组: 然后我有功能: 但是,其中仍然包含两个元素。 我想过另一种删除它的方法,那就是使用“键”,但是我似乎找不到任何有关获得键值的东西。 问题答案: 首先,您需要绑定到回调函数的范围。如果要访问用于从合成事件呈现按钮的react对象实例,则可以使用privat

  • 使用react+react-dnd实现了类似上图的效果,不过目前的问题是,现在只能实现往后追加,不能实现从中间插入,如果要实现从中间插图需要获取右边每个子组件的位置 由于右边的效果是通过遍历实现的,所以通过ref的方法只能拿到最后一个元素的位置信息

  • antd的Tabs操作children子组件dom,使用forwardRef暴露子组件的方法后 ,没有激活过的Tab无法在父组件获取对应的ref对象,导致无法调用子组件的方法,有什么办法在不点击子组件的Tab,还能获取ref对象吗? 点击子组件Tab,ref对象就有

  • 问题内容: 我想呈现输入的HTML5属性,以便可以将jquery图像选择器与react一起使用。我的代码是: 问题是即使正确地以a形式传递,它也不会在HTML中呈现- 只是呈现为。如何使变量正确传递到HTML? 问题答案: 您不应将JavaScript表达式用引号引起来。 查看JavaScript Expressions文档以获取更多信息。

  • 提前谢了。我有一个状态数组,如下所示。 我需要添加一个项目到状态数组,我发现我们不需要做状态突变。如何使用PrevState设置状态。 如何调用set State以追加此状态数组。 像这样的东西?

  • 问题内容: 如果我有一个对象数组,并且想将Angular模型绑定到基于过滤器的元素之一的属性,该怎么做?我可以用一个具体的例子更好地解释: HTML: 控制器: JSBin:http://jsbin.com/adisax/1/edit 我想将第二个输入过滤为具有’C’等级的主题,但是我不想将模型绑定到该 等级 ;我想将其绑定到等级为“ C”的主题的 标题 。 这可能吗?如果可以,怎么做? 问题答案