在选项卡之间切换时避免在 React 中重新渲染

Kir*_*han 5 javascript reactjs material-ui

我有一个使用 material-ui 创建选项卡的反应应用程序。

<div className={classes.root}>
  <AppBar position="static">
    <Tabs value={value} onChange={handleChange}>
      <Tab label="Item One" />
      <Tab label="Item Two" />
      <Tab label="Item Three" />
    </Tabs>
  </AppBar>
  {value === 0 && <TabContainer id={1}>Item One</TabContainer>}
  {value === 1 && <TabContainer id={2}>Item Two</TabContainer>}
  {value === 2 && <TabContainer id={3}>Item Three</TabContainer>}
</div>
Run Code Online (Sandbox Code Playgroud)

编辑 Material-UI 选项卡

TabContainer 是一个功能组件,并进行一些繁重的计算。
在选项卡之间切换时是否可以防止 TabContainer 重新渲染?

更新:
检查我的答案以获取带有 React 功能组件和 css 类的解决方案。

Kir*_*han 9

更新/部分解决方案
使用下面的代码(基于Rahul Jain 的答案),使用 css 类显示活动 TabContainer,记忆化的函数似乎真的被记忆化了。

    const useTabContainerStyles = makeStyles((theme: Theme) =>  createStyles({
        root: {
          padding: 8 * 3
        },
        tabcontainerInActive: {
          display: "none"
        }
      })
    );

    function TabContainer(props: TabContainerProps) {
      const styles = useTabContainerStyles({});
      console.log("In TabContainer");
      const doubleValue = useMemo(() => double(props.id), [props.id]);
      return (
        <Typography
          id={props.id.toString()}
          component="div"
          className={classnames(styles.root, {
            [styles.tabcontainerInActive]: !props.active
          })}
        >
          {props.children + " " + doubleValue}
        </Typography>
      );
    }

    export default function SimpleTabs() {
      const classes = useStyles({});
      const [selectedTab, setSelectedTab] = React.useState(0);

      function handleChange(event: React.ChangeEvent<{}>, newValue: number) {
        setSelectedTab(newValue);
      }

      return (
        <div className={classes.root}>
          <AppBar position="static">
            <Tabs value={selectedTab} onChange={handleChange}>
              <Tab label="Item One" />
              <Tab label="Item Two" />
              <Tab label="Item Three" />
            </Tabs>
          </AppBar>
          {/*  */}
          <TabContainer id={0} active={selectedTab === 0}>
            Item One
          </TabContainer>
          <TabContainer id={1} active={selectedTab === 1}>
            Item Two
          </TabContainer>
          <TabContainer id={2} active={selectedTab === 2}>
            Item Three
          </TabContainer>
        </div>
      );
    }
Run Code Online (Sandbox Code Playgroud)

  • @Joe 按照您的建议更新了使用 CSS 类的代码。 (3认同)
  • 我建议不要这样做。让默认容器 CSS 类具有“display: none”,然后拥有一个样式为“display: block”的类(例如“tab-container--active”)会更容易,该类在“selectedTab ===”时添加索引`。无需重新渲染,更容易测试,对于其他查看代码的人来说也更直观。 (2认同)

小智 5

为了防止 TabContainer 重新渲染。你必须

  1. 一次呈现所有 TabContainer 数据,而不是基于值呈现。
  2. 您必须使用 CSS,并且必须仅显示当前处于活动状态的选项卡。
  3. 此外,您可以将组件设为 PureComponent,或者您可以覆盖shouldComponentUpdate()生命周期方法以停止对您的React 组件进行额外的重新渲染。