Preact: className is sometimes enumerable when it shouldn鈥檛 be

Created on 3 Jan 2020  路  9Comments  路  Source: preactjs/preact

In https://codesandbox.io/s/solitary-smoke-e4ouv (10.1.1):

  • The class鈫抍lassName aliasing code (1) seems to mutate the props to add a non-enumerable getter
  • the forceUpdate (2) call seems to recycle the mutated props inside props.children (3)
  • something weird happens and className becomes enumerable, even though it was never explicitly named (see output)
beginner-friendly

All 9 comments

I don't know if it's related, but version 10.1.0 broke my Emotion styled components using preact/compat: https://codesandbox.io/s/cocky-stallman-27oh3. Change to version 10.0.5, for ex, and you'll see it working.

@eliseumds it's likely not related and I'm confused because the linked sandbox doesn't use styled-components but emotion. Can you file a new issue for that?

@marvinhagemeister Emotion also has a styled functionality, but I should have foreseen the confusion, my bad. Issue created: https://github.com/preactjs/preact/issues/2275

Not sure if it's related or not, but after I upgraded to react 10.2 some of my old code did break. What I'm seeing is that my when using class attribute/property everywhere, and then using {...props} class={`${props.class} extra-class`} I don't get that extra-class unless i use className=... syntax instead. For now i downgraded back to 10.0.5 as I can't get to the bottom of this right

@Inviz I'm unable to create a scenario where the error occurs. Can you try making a codesandbox where the issue is reproducible? This would help tremendously in getting it fixed.

First thing is that it seems the issue only appears if preact/compat (or its parts) included anywhere in the app. I'm using it for Suspense/lazy, but it also includes some undesirable behavior like this class name. I wonder if Suspense/Lazy can be moved into another sort of module instead.

Trying to make codesandbox example, but i somehow can't include preact/compat in there just yet...

I'm really sorry but I can't couldn't up with the reprodicble example. What i'm seeing is that:
1) If I include preact/compat anywhere in the bundle
2) And I only use class attribute
3) I get both class and className in some specific component in props (I introspected props with JSON.stringify(props) and both keys are there).
4) In my case I'm putting a rendered component through props to another component. But I still couldn't make the same happen in isolated example
5) I never use forceUpdate anywhere in my code, however I have quite a set up with hooks and multi-pass render

I think this is consistent with bug report above that className becomes enumerable "sometimes". Now when props have both className and class, preact seems to pick up the className instead. So in my case where I used something like <Button {...props} class="..." />, if props already had className, the given class would be ignored.

@JoviDeCroock told me on Slack that he found an issue with compat. Can you please give some details on that?

I apologize for not being able to conjure working reproducble example again. Seems that there're some side-effects/lifecycle stuff that I can't replicate

Found the cause of this while working on a fix for #2275 :tada:

Thank you so much!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

matthewmueller picture matthewmueller  路  3Comments

jasongerbes picture jasongerbes  路  3Comments

KnisterPeter picture KnisterPeter  路  3Comments

youngwind picture youngwind  路  3Comments

mizchi picture mizchi  路  3Comments