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

fak*_*442 1 javascript tabs reactjs material-ui

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

我还添加了一个例子。

标签页组件:

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>
  );
}
Run Code Online (Sandbox Code Playgroud)

子组件:

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" }}
                        />}
                />
  );
}
Run Code Online (Sandbox Code Playgroud)

您可以在 StackBlitz 中看到问题,当您检查第一个选项卡中的字段,然后切换第二个选项卡并返回第一个选项卡时,复选框正在重置,并且“someChecked”状态恢复为默认值。

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

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

fak*_*442 5

我找到了解决方案。我在这里分享给以后遇到这个问题的人。

我们用 CSS 技巧解决了这个问题。我们将条件设置为display:none样式,这样就不存在卸载/挂载和重新渲染的问题。

示例代码:

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