JSX children including {" "} are printed oddly
See original GitHub issueRelated to https://github.com/prettier/prettier/issues/4223 and https://github.com/prettier/prettier/issues/4941.
I have some intentional {" "}
children in this code, which prettier sometimes collapses and sometimes does not. The end result is that some explicit spaces (which are important in this code, but not normally super important in JSX) can be easy to miss, because they are converted to implicit spaces.
I’m not sure how to handle this without breaking all the expectations people have elsewhere, but I’m opening this issue to track this.
Prettier 1.15.1 Playground link
--parser babylon
Input:
const ClassDeclarationComponent: React.FunctionComponent<Props> = ({
node,
renderChild,
renderChildren,
}) => {
return (
<>
{renderChildren("decorators", <Break />)}
{node.decorators && node.decorators.length > 0 ? <Break /> : null}
{node.declare /* TS */ ? (
<>
<Word value="declare" />
{" "}
</>
) : null}
{node.abstract /* TS */ ? (
<>
<Word value="abstract" />
{" "}
</>
) : null}
<Word value="class" />
{node.id ? (
<>
{" "}
{renderChild("id")}
</>
) : null}
{renderChild("typeParameters")}
{node.superClass ? (
<>
{" "}
<Word value="extends" />
{" "}
{renderChild("superClass")}
{renderChild("superTypeParameters")}
</>
) : null}
{node.implements ? (
<>
{" "}
<Word value="implements" />
{" "}
{renderChildren("implements", ", ")}
</>
) : null}
{" "}
{renderChild("body")}
</>
);
};
Output:
const ClassDeclarationComponent: React.FunctionComponent<Props> = ({
node,
renderChild,
renderChildren
}) => {
return (
<>
{renderChildren("decorators", <Break />)}
{node.decorators && node.decorators.length > 0 ? <Break /> : null}
{node.declare /* TS */ ? (
<>
<Word value="declare" />{" "}
</>
) : null}
{node.abstract /* TS */ ? (
<>
<Word value="abstract" />{" "}
</>
) : null}
<Word value="class" />
{node.id ? <> {renderChild("id")}</> : null}
{renderChild("typeParameters")}
{node.superClass ? (
<>
{" "}
<Word value="extends" /> {renderChild("superClass")}
{renderChild("superTypeParameters")}
</>
) : null}
{node.implements ? (
<>
{" "}
<Word value="implements" /> {renderChildren("implements", ", ")}
</>
) : null}{" "}
{renderChild("body")}
</>
);
};
Expected behavior:
Not sure.
Issue Analytics
- State:
- Created 5 years ago
- Reactions:1
- Comments:5 (5 by maintainers)
Top Results From Across the Web
Why using the `children` prop makes `React.memo()` not work
It's an obvious issue in retrospect: React.memo() shallowly compares the new and the old props and short-circuits the render lifecycle if they're the...
Read more >React.Children with non-element children - Stack Overflow
Children accepts only valid React elements, so the fact that child function is ignored looks odd. How does React.Children treat non-element ...
Read more >React Children: The misunderstood prop - Netlify
Let's go through step by step why children are weird, so you can understand them better. Again: React children. Not humans.
Read more >JSX In Depth - React
Functions as Children Children passed to a custom component can be anything, as long as that component transforms them into something React can...
Read more >JSX: The Confusing Parts - React Training
Namely: What is JSX and Why is it weird sometimes? ... The most common plugin paired with React is Babel -- a JavaScript...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Maybe a good heuristic would be: if there aren’t any text in children, print them all in separate lines
EDIT: we do that already, so I guess I mean not treating
{" "}
as text if there isn’t more textI might even go as far as to also consider the following “no text in children”, even though there’s a string child other than the space:
With any change related to this, though, we need to be careful not to introduce situations where JSX formats differently on a second run. This is a low-priority issue anyway