【问题标题】:Avoid re-rendering in React when switching between tabs在选项卡之间切换时避免在 React 中重新渲染
【发布时间】:2020-01-18 07:15:11
【问题描述】:

我有一个使用 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>

TabContainer 是一个函数式组件,会进行一些繁重的计算。
是否可以防止 TabContainer 在标签之间切换时重新渲染?

更新:
查看我的 answer 以获取包含 React 功能组件和 css 类的解决方案。

【问题讨论】:

    标签: javascript reactjs material-ui


    【解决方案1】:

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

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

    【讨论】:

    • 我已经尝试过您的建议 1 + 2,但没有成功。
    • 根据您的建议,我能够使用反应钩子和功能组件来实现这一点。检查我的更新。
    【解决方案2】:

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

        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>
          );
        }
    

    【讨论】:

    • 我建议不要这样做。让默认容器 CSS 类具有 display: none 然后具有样式为 display: block 的类(例如 tab-container--active)会更容易,该样式会在 selectedTab === index 时添加。无需重新渲染,更容易测试,并且对于其他查看代码的人来说更直观。
    • @Joe 按照您的建议更新了使用 CSS 类的代码。
    • @KiranMohan 尝试实现你的灵魂,但没有运气。每次重新呈现选项卡容器时单击选项卡。
    猜你喜欢
    • 2020-12-21
    • 1970-01-01
    • 2020-11-16
    • 1970-01-01
    • 2019-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多