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

fix 1360 #1381

Closed
wants to merge 2 commits into from
Closed

fix 1360 #1381

wants to merge 2 commits into from

Conversation

Jokcy
Copy link
Contributor

@Jokcy Jokcy commented Aug 6, 2020

Corresponding issue (if exists):

#1360

What would you like to add/fix?

fix memory leak with dynamic styles

@Jokcy Jokcy requested a review from HenriBeck as a code owner August 6, 2020 10:16
@Jokcy
Copy link
Contributor Author

Jokcy commented Aug 6, 2020

@Jokcy
Copy link
Contributor Author

Jokcy commented Aug 6, 2020

image

It seems some error with CI config

@@ -94,15 +94,15 @@ export default function jssNested(): Plugin {
// Replace all $refs.
selector = selector.replace(refRegExp, replaceRef)

container.addRule(selector, style[prop], {...options, selector})
container.addRule(selector, style[prop], {...options, selector, safeReplace: true})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

proposal: lets make a new method - replaceRule which will do exactly this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you mean, we add relpaceRule in StyleSheet:

replaceRule(name: string, decl: JssStyle, options?: RuleOptions): Rule | null {
  if (options) {
    options.safeReplace = true
  }
  else {
    options = { safeReplace: true }
  }

  this.addRule(name, decl, options)
}

or just implement a same addRule method expect safeReplace logic ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or just implement a same addRule method expect safeReplace logic ?

this, yeah

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems to me that it would be very obvious semantics

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But if we do that, which not add safeReplace option, we may have to add a replace method to RuleList. That adds a lot of extra code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or maybe we can implement addOrReplace to share the same logic

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will have a try

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I def. don't want to add a lot of extra code, it should share the logic

@Jokcy
Copy link
Contributor Author

Jokcy commented Aug 13, 2020

@kof I updated code to use replaceRule, pleace review the code. And I have to update two test cases in React-JSS

@@ -321,9 +321,9 @@ export default ({createStyledComponent}) => {
color: red;
}
}
.container-d2-2 { }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it broke the order it seems, otherwise why is this diff here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you don't konw the reason, I guess I need to go deep to find out the reason

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, can't tell just by looking at this changes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found the reason, it because React-jss use sheet.addRule to handle dynamic rules, in this case, it will add:

container: {
          display: 'block',
          '@media (min-width: 0px)': {
            color: ({color}) => color
          }
        }

because it directly using addRule so container will be added as container-d0, then jss will processStyle which:

{
          display: 'block',
          '@media (min-width: 0px)': {
            color: ({color}) => color
          }
        }

then using replaceRule to @media (min-width: 0px) since it is a NestedConditional rule, so it won't increase the counter of RuleList.

In the code before, we use addRule in nest plugin, so the dynamic @media (min-width: 0px) will increase the counter.

Now I'm wondering if it is safe to use replaceRule for all case, even if I can pass all the test cases.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where do you see the danger here? I might not be understanding the problem correctly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let key = name
    if (!isReplace && name in this.raw) {
      key = `${name}-d${this.counter++}`
    }

    this.raw[key] = decl

in this case, if we use old code, this.raw will be:

{
  container: {},
  @media (min-width: 0px): {},
  container-d0: {},
  @media (min-width: 0px)-d1: {},
}

the new add rule won't replace old rule.

The main problem is, if people use addRule to add a nest rule, then it will use replaceRule inside. I think if people want to add rule, it should be really add but not replace.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add a test that reproduces the "wrong" behavior in react-jss? So we can think of better ways of fixing it.

/**
* See issue https://github.com/cssinjs/jss/issues/1360
*/
replaceRule(name: string, decl: JssStyle, options?: RuleOptions): Rule | null {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the idea of adding a new method replaceRule was to completely avoid passing an option ala isReplace, because it adds a bit of indirection

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I finally get your point...

@tokiroto
Copy link

There seem no merge due to tests failed. Any progress with that?

@kof
Copy link
Member

kof commented Nov 13, 2020

No this got stuck because we need a test, @Jokcy do you have time to add it?

@ohazda
Copy link

ohazda commented Nov 20, 2020

Looks like this bug causes lots of issues. Hope you can get it merged soon. 🙏🏻

@kof
Copy link
Member

kof commented Nov 21, 2020

This is not gonna be merged unless we have a test that fails with the current behavior. Once someone creates a test like that we can validate this fix and some other ideas of how to fix it. Feel free to create separate PR if needed with just a failing test.

@tokiroto
Copy link

Any update on merge?

@kof kof added the needs tests We can't merge a change without tests verifying it's behaviour label Jun 27, 2021
@kof
Copy link
Member

kof commented Jun 27, 2021

We NEED a test like mentioned 2 times above. Without a test we can not merge this PR. Anyone feel free to step in and write a test for the wrong behaviour that causes the bug. It seems like we should write a few unit tests that uses the API the same way react-jss does like described here https://github.com/cssinjs/jss/pull/1381/files#r470438013

Or alternatively write a test in react-jss that reproduces this behaviour.

@seiyab
Copy link
Member

seiyab commented Sep 23, 2021

I wrote a test for this problem.
And unfortunately, my test shows that this PR does NOT resolve the issue.
This might be my failure because @Jocky wrote a demo #1381 (comment) and they should have verified that it resolved the issue.
Now we cannot access their demo code.
Need help.

This is the test, that fails.
https://github.com/seiyab/jss/blob/16346eaaa627a9c66b9ec096e48968227e903a00/packages/react-jss/tests/dynamicStyles.js#L44-L93

@kof
Copy link
Member

kof commented Oct 16, 2021

I think we got this finally addressed in #1563

@kof kof closed this Oct 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs tests We can't merge a change without tests verifying it's behaviour
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants