React MUI Tab组件导致重新渲染和删除子状态



我们正在尝试使用React MUI设计一个标签页。我们希望每个选项卡都有一个子组件。当我们将这些子组件添加到没有Tab的单个页面时,没有问题,但是当我们将它们添加到MUI的Tab和TabPanel组件时,我们有一个重新呈现的问题。当从一个选项卡切换到另一个选项卡时,前一个选项卡中的所有字段和状态都将被删除。

我也添加了一个这样的例子。

TabPage组件:

export default function LabTabs() {
const [value, setValue] = React.useState('1');
const handleChange = (event: React.SyntheticEvent, newValue: string) => {
setValue(newValue);
};
return (
<Box sx={{ width: '100%', typography: 'body1' }}>
<TabContext value={value}>
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
<TabList onChange={handleChange} aria-label="lab API tabs example">
<Tab label="Item One" value="1" />
<Tab label="Item Two" value="2" />
<Tab label="Item Three" value="3" />
</TabList>
</Box>
<TabPanel value="1">
<Deneme />
</TabPanel>
<TabPanel value="2">Item Two</TabPanel>
<TabPanel value="3">Item Three</TabPanel>
</TabContext>
</Box>
);
}

子组件:

export default function Deneme() {
const [value, setValue] = React.useState('1');

const handleChange = (event: React.SyntheticEvent, newValue: string) => {
setValue(newValue);
};
const [someChecked, setsomeChecked] = React.useState(false);
const someChanged = (event: React.ChangeEvent<HTMLInputElement>) => {
setsomeChecked(event.target.checked);
};
return (
<FormControlLabel
label="Some Check Name"
control={
<Checkbox
checked={someChecked}
onChange={someChanged}
inputProps={{ "aria-label": "primary checkbox" }}
/>}
/>
);
}

你可以在StackBlitz中看到这个问题,当你在第一个选项卡中勾选字段,然后切换到第二个选项卡,然后回到第一个选项卡,复选框正在重置并且" someechecked& quot;状态恢复为默认值。

https://stackblitz.com/edit/react-iari77?file=demo.tsx

所以我看不出问题,如果我们不使用子组件是没有问题的,但是我们必须使用…

我找到了解决方案。我在这里分享给那些将来有这个问题的人。

我们修复了CSS技巧的问题。我们将display:none样式设置为条件,这样就不会出现卸载/加载和重新渲染的问题。

示例代码:

<TabPanel value={value}>
{props.tabItems.map((item) =>  
{return 
<div style={{ display: item.value == value ? 'block' : 'none' }}> 
{item.content}
</div>
})} 
</TabPanel>

这是在子选项卡组件中管理相关状态时的实际行为。为了持久化每个子组件的someChecked状态,您必须在父组件LabTabs中管理它们。

在你当前的实现中,当你从一个选项卡移动到另一个选项卡时,实际发生的是你之前的选项卡组件被卸载,下一个选项卡组件被加载。因此,以前选项卡中的所有状态都将被删除。这就是为什么当你回到上一个选项卡时,状态似乎被删除了。

为了避免父组件中的管理状态,并将它们作为props传递给子组件。

最新更新