Expected behavior:
The root component of a React app that is using react-jss for styles should be able to re-render and not break the styling of its child components.
Describe the bug:
This bug occurs when the root node of a React app re-renders and then later an instance of a child component unmounts when another instance of the same component mounts.
From my research, it looks like this is caused by the indexOf check in RuleList's remove function. The indexOf uses strict equality checks which fails to find a match after the re-render. The rule is no longer strictly equal due to something with how the provider works. This means that you are splicing with a -1 index, effectively removing the wrong items from the list.
['a', 'b', 'c'].splice(-1, 1)
// ['c']
This could be fixed by refactoring that line in RuleList from:
this.index.splice(this.index.indexOf(rule), 1)
to:
const index = this.index.findIndex(v => v.key === rule.key);
if (index > -1) {
this.index.splice(index, 1)
}
You could also update the provider so that it doesn't return a different object instance.
Reproduction:
You can see an example of this failure on this codepen. In that example one instance of the component is unmounting while another is mounting. The cleanup function for the first instances's dynamic styles runs after the second instance has created its sheet and it removes the new sheet.
Versions (please complete the following information):
- jss: 10.9.2
- Browser [e.g. chrome, safari]: Chrome
- OS [e.g. Windows, macOS]: macOS
This is possibly related to #917, though that issue has been closed.
Expected behavior:
The root component of a React app that is using
react-jssfor styles should be able to re-render and not break the styling of its child components.Describe the bug:
This bug occurs when the root node of a React app re-renders and then later an instance of a child component unmounts when another instance of the same component mounts.
From my research, it looks like this is caused by the
indexOfcheck in RuleList's remove function. TheindexOfuses strict equality checks which fails to find a match after the re-render. The rule is no longer strictly equal due to something with how the provider works. This means that you are splicing with a -1 index, effectively removing the wrong items from the list.This could be fixed by refactoring that line in RuleList from:
to:
You could also update the provider so that it doesn't return a different object instance.
Reproduction:
You can see an example of this failure on this codepen. In that example one instance of the component is unmounting while another is mounting. The cleanup function for the first instances's dynamic styles runs after the second instance has created its sheet and it removes the new sheet.
Versions (please complete the following information):
This is possibly related to #917, though that issue has been closed.