I have a react application using material-ui to create tabs.
<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>
The TabContainer is a functional component and does some heavy computation.
Is it possible to prevent TabContainer from re-rendering when switching between tabs?
Update:
Check my answer for a solution with React functional components and css classes.
1. Memoization using useMemo() and UseCallback() Hooks. Memoization enables your code to re-render components only if there's a change in the props. With this technique, developers can avoid unnecessary renderings and reduce the computational load in applications.
Preventing Re-Renders: The Old Way To prevent the render method from being called, set the return to false, which cancels the render. This method gets called before the component gets rendered. Sometimes you may want to prevent re-render even if a component's state or prop has changed.
To get rid of your infinite loop, simply use an empty dependency array like so: const [count, setCount] = useState(0); //only update the value of 'count' when component is first mounted useEffect(() => { setCount((count) => count + 1); }, []); This will tell React to run useEffect on the first render.
The reason why this happens is an intentional feature of the React. StrictMode . It only happens in development mode and should help to find accidental side effects in the render phase.
In order to prevent TabContainer from re-rendering. You have to
Update/Partial Solution:
With the below code (based on Rahul Jain's answer) using css classes to display the active TabContainer, the memoized functions seems to be really 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>
);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With