I wanted to move styled-jsx code to a dedicated variable and then inject it into the render()
method like this:
const divstyle = (
<style jsx>{`
div {
color: red;
}
`}
</style>
);
return (
<div>
<div>foo</div>
{divstyle}
</div>
);
This will inject the style into the DOM but not scoped. In console I see this error:
Warning: Received `true` for a non-boolean attribute `jsx`.
If you want to write it to the DOM, pass a string instead: jsx="true" or jsx={value.toString()}.
If I move the <style jsx>
part from the variable back into the render method, everything works perfectly.
What's wrong? Isn't it possible to to use styled-jsx outside of render()
?
Whenever you see that error it means that styled-jsx didn't transpile your code at all therefore the style
element is rendered as regular html and jsx
is an invalid prop for it.
If you want to extract your styles to a variable you can use css
from styled-jsx/css
like so:
import css from 'styled-jsx/css'
const divstyle = css`
div { color: red }
`
export default () => (
<div>
<div>foo</div>
<style jsx>{divstyle}</style>
</div>
)
However I wouldn't recommend that since css
produces both scoped and global styles.
We need to optimize that in the future so that styles like that are tree-shakeable and tools can do dead code elimination.
@giuseppeg Aww, to bad :-( I wanted to use this approach to put each style block into an own variable so ESLint can find unused variables/styles.
Any other solutions to use css (with media queries) in Next but with the option of finding dead css code?
@giuseppeg Hm, I also tried your approach but it doesn't work. Gives me this error:
Module build failed: SyntaxError: The Identifier
divstyleis either
undefinedor it is not an external StyleSheet reference i.e. it doesn't come from an
importor
requirestatement
@valnub that feature is available with [email protected] which is included with [email protected]
Note: The approach using css with [email protected] works very nicely, no issues. I don't see any global styles either.
Thanks a lot @giuseppeg for helping :-)
@valnub if you look at your transpiled code you will notice that
css`
div { color: red }
`
is transpiled to something like this https://github.com/zeit/styled-jsx/blob/master/test/__snapshots__/external.js.snap#L4-L7 or this https://github.com/zeit/styled-jsx/blob/master/test/__snapshots__/external.js.snap#L81-L85
@giuseppeg If the styles would be applied globally, wouldn't that mean that all div elements on the page would be selected? I tested that and don't see that effect.
I didn't say that the styles apply :) I just said that css
produces both scoped and global styles so in your bundle you end up having unnecessary css that with the current implementation can't be removed by tools.
@giuseppeg Ah, thanks for clarifying. I think that's no problem because I'm referencing each style block through a variable. ESLint should then be able to tell if there are dead styles when a variable isn't used any more.
ESLint doesn't catch that because it runs on the source code, not the transpiled one.
@giuseppeg Ah, I see there was a misunderstanding. You were talking about styles that aren't used on the current page but required in other pages/component. I was talking about dead code in general which isn't used anywhere.
However, so using the approach with css and styled-jsx will lead to loading more code in the bundle than necessary.
You said that this needs to be optimized in the future. Are there already plans to fix this anytime soon? If yes, I think this would be a very nice working solution for us.
When I have some spare time to work on it, not that easy recently :) https://github.com/zeit/styled-jsx/issues/345
@giuseppeg Awesome, thanks 馃憤
This looks bad news and messy...
I thought that using styled-jsx (that looks nice for me and that comes by default) would prevent from having to hack.
Is there something planned to fix that?
Otherwise the best and cleaner solution for me will be to move to another css-in-js like styled-components
(I don't really want, I found next js default solution nice enough on the paper...)
馃様.
@MacKentoch fixing this in https://github.com/zeit/styled-jsx/issues/345 This will ship this or next month with v3
Thank you for your prompt reply @giuseppeg that sounds really good news!
I definitely prefer styled-jsx
so I'm glad I still can bet on it and will keep defend it at the office
馃槈
I found the same issue with the new feature of React empty jsx tag:
<>
<div className={'content'}>
{ props.children}
</div>
<style jsx>{`
.content {
padding: 0 5%;
width: 100%;
height: 100%;
}
`}</style>
</>
The warning comes back:
Warning: Received `true` for a non-boolean attribute `jsx`.
If you want to write it to the DOM, pass a string instead: jsx="true" or jsx={value.toString()}.
Is there any plan to fix it 馃槅
use <React.Frament>
for now, styled-jsx is not Babel7 compatible yet. We'll add support for that in styled-jsx v3
Hey @giuseppeg just noticing styled-jsx v3 is out, and I'm using nextjs 7 which uses 3.0.3 but this issue still exists.
Just wondering if I'm doing something wrong, or it hasn't quite made it to v3 yet?
@Stephen2 you mean the issue with fragments? If so yes, I haven't had the time to add fragments support yet. I will try to do that this week or the next one:)
Oh cool! Thanks very much, I'll keep my eyes out
Most helpful comment
I found the same issue with the new feature of React empty jsx tag:
The warning comes back:
Is there any plan to fix it 馃槅