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.
See above ^
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.
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.
Rendering apps twice costs:
Ask yourself, if you were Captain Picard, what would you do in this situation? 馃槅
| Tech | Version |
| ----------- | ------- |
| Material-UI | v4.9.8 |
| React | 16.13 |
| Browser | Chrome 80 |
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.
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 timewithStyles does not effect component rendersIs 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 鉂わ笍
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.
@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/.
You're right! Thanks dude!
You're awesome 馃挭
Most helpful comment
@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/.