cssinjs / cssinjs/jss

Style block un-renders when any param used - since v10.0

Open
#1,646 1 comment 4 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
7.1k
Forks
386
PR merge metrics
No merged PRs in 30d

Description

__Expected behavior:__
Styles for a React component should remain rendered until component unmounts.

__Describe the bug:__
When any param is used in a stylesheet, **all the styles are immediately deleted after rendering.** This issue exists in every v10.x version.

__Reproduction:__
This bug can be seen in the sandbox demo _provided by this package_, with zero changes:
- https://codesandbox.io/s/j3l06yyqpw

In the demo a `theme` prop is passed and used in the stylesheet, which is all it takes to trigger the bug. To see the issue:

1. Inspect the H1 element
2. In the Styles panel, click _either_ of the `` tags created by JSS
3. The referenced style tag element is displayed
4. Observe that the style tag is EMPTY - no style rules are rendered

**Attached are 2 screenshots that illustrate the steps above, using the _unaltered_ sandbox.**

__Versions (please complete the following information):__
- jss: 10.0.0 onwards (Did not test in v9.x)
- Browser: Chrome (latest)
- OS: Windows AND macOS

I tried multiple versions all the way back to v10.0.0 to try finding a version without the problem, but every version has it. I could not go back to v9.x because we use the `createUseStyles` hook in our app, which was added in v10.

## Why has this serous bug never been noticed?

The browser 'caches' the styles when they are rendered, so even though they immediately _unrender_, the browser still applies them. Therefore in most scenarios, the UI renders as expected, even though the styles are no longer in the DOM.

I discovered the bug when we started using the same common component in many views. This common layout wrapper uses params so triggers the bug. We found that as we navigated between views, the styles for the component 'disintegrated'. For example, on the first navigation, the background color disappeared. On the second navigation, the padding disappeared. By the third navigation, _none_ of the component styles were still being applied.

The navigation causes rerenders of the page section that contain the element, causing a _new element_ to be created. It seems that each time a new element was created, the browser _noticed_ that the CSS was no longer present in the DOM, so the styles were no longer applied. I don't know why all the styling did not disappear at once, but that is not really important.

__Managing expectations:__

I saw a similar bug that had a recent PR. I implemented that change but it did not fix this issue. There are numerous bugs related to the use of params, but can't find anything like this one.

I did try to trace the code to see if I could find where the logic bug is, but didn't find it. It would require a significant investment of time to reverse engineer the logic used, and I am not able to invest that right now.

My GUESS is that it is related to the logic that separates dynamic properties from static properties, but I have nothing to support that hypothesis.

It is only dumb luck that browser caching has hidden this major bug until now. There is no workaround I can find, so in our app I will remove all dynamic params as this functionality is fundamentally _broken_,. We can no longer rely on browser caching to hide the issue for our use cases.

![Snag_50bf08f9](https://github.com/cssinjs/jss/assets/301226/d62fe473-4b9d-4657-843e-ae3cb4290964)

![Snag_50bf31be](https://github.com/cssinjs/jss/assets/301226/3342c81e-0ff2-476f-a652-b85dd03d911c)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.