-
-
Notifications
You must be signed in to change notification settings - Fork 32.7k
Description
Steps to reproduce
Demo: https://codesandbox.io/p/sandbox/mui4-make-styles-repro-c7h95p?file=%2Fsrc%2FList.js%3A19%2C22
Steps:
- Switch the list on by clicking TOGGLE LIST.
- Observe that stylesheet LIST appears.
- Switch the list off by clicking TOGGLE LIST button again.
- Observe that stylesheet LIST is not removed.
Current behavior
LIST stylesheet remains in the DOM after the component is unmounted, leading to potential memory leaks and stale styles.
Expected behavior
LIST stylesheet should be properly detached and cleaned up even when React skips effects due to state updates during render.
Context
In our legacy project, we dynamically mount one of several applications on the page at any given time. Each application is delivered as a separate bundle and includes its own instance of Material-UI. We commonly use state updates during render to optimize our workflow. As a result, we’ve encountered some similar issues where stylesheets from a previously mounted application are not properly cleaned up, leading to conflicts with the styles of the currently mounted application.
We investigated a bit this issue and found out that it occurs because useSynchronousEffect
stores its cleanup function in a local variable, which is lost if React skips the effect.
Also we fixed the issue by using a ref for the cleanup function, so it persists across renders and ensure proper cleanup.
For now we have patched makeStyles module locally. I'm going to create PR later.
Your environment
Browser: Chrome (latest)
Material UI version: 4.11.3
React: ^17
Search keywords: useSynchronousEffect, orphaned stylesheets, effect skipping, React, makeStyles, cleanup bug