Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using the makeStyles / useStyles() pattern causes React apps to render twice #20313

Closed
NawarA opened this issue Mar 28, 2020 · 5 comments
Closed
Labels
support: question Community support but can be turned into an improvement

Comments

@NawarA
Copy link

NawarA commented Mar 28, 2020

Let me start by saying, I ❤️ MUI. K, lets dive in:

I log how frequently my react app renders, just so I maintain fine grain control over DOM renders / reflows. I noticed whenever I start my react app, it rendered twice at the root level. I began investigating the root cause and I've narrowed it down to:

import React from "react";
import { makeStyles } from "@material-ui/core/styles";

export default ()=> {
 const classes = useStyles();
};

const useStyles = makeStyles(()=> { ... });

This causes react apps to render twice. Here's the thing, on the first render, classes is fully populated and ready to go. The second render returns the same classes object, with no differences --> thus the second re-render is unneeded and wasteful.

Current Behavior 😯

See above ^

Expected Behavior 🤔

const classes = useStyles() does not effect component re-rendering.

Using withStyles instead of makeStyles (which have the same outcome of making a classes object available), DOES NOT cause the component to render twice. It's expected the makeStyles and withStyles do not effect rendering. withStyles is working that way, makeStyles is not.

Steps to Reproduce 🕹

See the codesandbox links below for evidence of the issue:

makeStyles renders twice
withStyles renders once

As you can see, withStyles has the correct behavior, and makeStyles, has the buggy behavior.

Context 🔦

Rendering apps twice costs:

  • money
  • wastes user resources
  • wastes planetary resources

Ask yourself, if you were Captain Picard, what would you do in this situation? 😆

Your Environment 🌎

Tech Version
Material-UI v4.9.8
React 16.13
Browser Chrome 80
@NawarA NawarA changed the title React apps render twice when initially using the makeStyles / useStyles() pattern Using the makeStyles / useStyles() pattern causes React apps to render twice initially Mar 28, 2020
@NawarA NawarA changed the title Using the makeStyles / useStyles() pattern causes React apps to render twice initially Using the makeStyles / useStyles() pattern causes React apps to render twice Mar 28, 2020
@eps1lon
Copy link
Member

eps1lon commented Mar 28, 2020

This codesandboxes use StrictMode (see index.js) which calls render twice. Depending on your component tree this causes issues if you have side effects during render (such as console.log or
++renderCount)

Rendering apps twice costs:

money
wastes user resources
wastes planetary resources

Not necessarily. What we care more in react are commits and even more is actual performance measurements. Render counting is a tool to identify issues but it does not necessarily imply you have a performance issue.

@eps1lon eps1lon closed this as completed Mar 28, 2020
@oliviertassinari oliviertassinari added the support: question Community support but can be turned into an improvement label Mar 28, 2020
@NawarA
Copy link
Author

NawarA commented Mar 29, 2020

It sounds like you're dismissing the issue.

Maybe I misread your comment, but it seems you're saying that React strict-mode causes components with makeStyles (but not withStyles) to render twice...which you believe is fine?

I'd like to point out, a second time, that in strict-mode:

  • makeStyles is forcing components render an extra time
  • withStyles does not effect component renders

Is makeStyles, by design, supposed to force components to render twice?

If so, this is intentional behavior. If not, this an issue.

I'd like to humbly request that you mark this behavior (makeStyles accidentally re-render components) as an open issue and resolve in v4 or v5, which is supposed to be strict-mode compliant 🙏

Much ❤️

@eps1lon
Copy link
Member

eps1lon commented Mar 29, 2020

Rendering twice is the whole point of StrictMode. We can't and shouldn't do anything about it. It's like asking someLibraryMethod to not execute twice after the app-developer called it twice.

makeStyles isn't forcing your component to render twice. StrictMode is. You can observe the same behavior with any other hook. It's not "my believe" that this is fine. This is by design of React. If you think rendering twice is a problem in StrictMode then the react repo would be more appropriate for discussion.

Both sandboxes render twice. It's hidden in withStyles though in the second sandbox.

@oliviertassinari
Copy link
Member

oliviertassinari commented Mar 29, 2020

@NawarA ⚠️ This double rendering is a development only behavior. It won't happen in production.

Proof: https://codesandbox.io/s/strictmode-w-and-wo-hooks-vex1m deployed in production: https://csb-vex1m.netlify.com/.

@NawarA
Copy link
Author

NawarA commented Mar 30, 2020

You're right! Thanks dude!

You're awesome 💪

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
support: question Community support but can be turned into an improvement
Projects
None yet
Development

No branches or pull requests

3 participants