Search code examples
javascriptreactjsreact-hooksmaterial-uistyled-components

Too many re-renders with MUI and styled component


Hi I tried to render a page that use MUI(Material-UI) and styled-component. I've useTheme and useMediaQuery to make my webapp responsive.I tried to make my app responsive and change the fontsize if it's a small device

The problem that I have is that there are too many rendering according to the console

I know the problem is about the if else statement with the useState, but I don't know what are other choices to make this possible

Here's the following code:

import React, { useState } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Button from '@material-ui/core/Button';
import { Link } from 'react-router-dom';
import Logojsam from '../../assets/icons/logo-jsam.png';

import useMediaQuery from '@material-ui/core/useMediaQuery';
import { useTheme } from '@material-ui/core/styles';

import styled from 'styled-components';
const useStyles = makeStyles((theme) => ({
  rightToolbar: {
    marginLeft: 'auto',
    marginRight: -10,
  },
  logo: {
    width: 185,
    height: 185,
    padding: '20px 0px',
  },
}));

const MyButton = styled(Button)({
  padding: '0 14px',
  fontSize: (props) => props.fontSize || '20px',
});



const Navbar = () => {
  const classes = useStyles();
  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
  const isMedium = useMediaQuery(theme.breakpoints.down('md'));

  const [fontSize, setfontSize] = useState();
 
  if (isMedium)
  {
    setfontSize('45px');
  }
    return (
      <div>
        <AppBar
          position="static"
          elevation={0}
          style={{
            background: 'white',
          }}
        >
          <Toolbar>
            <img className={classes.logo} src={Logojsam} alt="Bosch Logo" />
            {!isMobile && (
              <section className={classes.rightToolbar}>
                <MyButton fontSize={fontSize} component={Link} to="/">
                  About Us
                </MyButton>
                <MyButton component={Link} to="/community">
                  Community
                </MyButton>
                <MyButton component={Link} to="/community">
                  Activities
                </MyButton>
                <MyButton component={Link} to="/gallery">
                  Gallery
                </MyButton>
                <MyButton component={Link} to="/contact-us">
                  Contact Us
                </MyButton>
                <MyButton component={Link} to="/contact-us">
                  En
                </MyButton>
              </section>
            )}
          </Toolbar>
        </AppBar>
      </div>
    );
};

export default Navbar;



Thank you


Solution

  • useEffect() Hook lets you perform side effects in function components. As stated in the comments. by Jayce444, when you call setfontSize() inside the main body of the component, it triggers a re-rendering. Put that in to useEffect, and only re-run when isMedium changes

    import React, { useState, useEffect } from 'react';
    

    Then

    useEffect(() => {
      if (isMedium){
        setfontSize('45px')
      }
    }, [isMedium]); // Only re-run the effect if isMedium changes