Arco Tabs切换标签页后子组件状态会丢失怎么办?

技术思晨 阅读 18

大家好,我在用Arco Design的Tabs组件时遇到个问题:当切换标签页再切回来,里面的表单输入内容就清空了。我看了文档试过设置forceRenderkeepAlive属性,但好像没起作用。

这是我的代码片段:


import { Tabs } from '@arco-design/web-react';

const MyTabs = () => {
  const [activeTab, setActiveTab] = useState('1');

  return (
    <Tabs 
      activeKey={activeTab} 
      onChange={setActiveTab}
      // 已尝试过以下配置但无效
      // forceRender
      // keepAlive
    >
      <Tabs.TabPane key="1" label="表单页">
        <input type="text" defaultValue="初始值" />
      </Tabs.TabPane>
      <Tabs.TabPane key="2" label="展示页">内容2</Tabs.TabPane>
    </Tabs>
  );
};

输入框用了defaultValue,但切换标签后内容就会消失。有没有什么办法能保持状态不丢失呢?

我来解答 赞 3 收藏
二维码
手机扫码查看
2 条解答
Air-德超
这个问题我之前也踩过坑,说白了就是组件被卸载导致状态丢失了。你用的是 defaultValue,这玩意只会在组件第一次渲染时生效,切换标签页时组件重新渲染,值自然就没了。

解决办法其实不复杂,核心思路是让组件的状态能够持久化,或者干脆不让组件被销毁。我给你两个靠谱的方案:

第一种,改用受控组件的方式,把输入框的值绑定到父组件的状态里。这样即使组件被销毁再重建,值也会从父组件的状态中恢复。代码可以改成这样:

import { Tabs } from '@arco-design/web-react';
import React, { useState } from 'react';

const MyTabs = () => {
const [activeTab, setActiveTab] = useState('1');
const [inputValue, setInputValue] = useState('初始值'); // 维护输入框的值

return (
<Tabs
activeKey={activeTab}
onChange={setActiveTab}
>
<Tabs.TabPane key="1" label="表单页">
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)} // 更新状态
/>
</Tabs.TabPane>
<Tabs.TabPane key="2" label="展示页">内容2</Tabs.TabPane>
</Tabs>
);
};


第二种,如果你不想折腾受控组件,那就直接用 React.memo 或者 keep-alive 的思路,避免组件被销毁。Arco Design 的 Tabs 提供了一个 destroyOnHide 属性,默认是 true,你需要手动把它关掉:

<Tabs 
activeKey={activeTab}
onChange={setActiveTab}
destroyOnHide={false} // 关键点:不让组件被销毁
>
<Tabs.TabPane key="1" label="表单页">
<input type="text" defaultValue="初始值" />
</Tabs.TabPane>
<Tabs.TabPane key="2" label="展示页">内容2</Tabs.TabPane>
</Tabs>


这两种方式我都试过,绝对靠谱。第一种适合需要严格管理状态的场景,第二种更简单粗暴,适合快速解决问题。不过血泪教训提醒你,如果项目复杂度高,还是推荐用第一种,状态管理会更清晰。
点赞
2026-02-19 18:05
阳阳
阳阳 Lv1
省事的话直接用 value 替代 defaultValue,再把输入框换成受控组件就行。

const MyTabs = () => {
const [activeTab, setActiveTab] = useState('1');
const [inputValue, setInputValue] = useState('初始值');

return (


setInputValue(e.target.value)} />

内容2

);
};


forceRender 记得加上,不然默认不渲染非激活面板。
点赞 3
2026-02-12 21:40