marksy
marksy copied to clipboard
Inconsistent rendering of children
Hi there,
I've built a small component inside of which I want to render some text. The text, however, has curly braces inside of it, and this isn't playing nicely with the renderer. Here's a minimal working example:
import React, { createElement } from "react";
import marksy from "marksy/components";
const compile = marksy({
createElement,
components: {
Test(props) {
return (
<div>
This is a test.
<p>{props.children}</p>
</div>
);
}
}
});
compile("<Test>hi</Test>") // tree is an array with 1 element
compile("<Test>{hi}</Test>") // tree is an empty array!
Right now this is failing silently: I traced the issue to this catch, which is a no-op:
https://github.com/cerebral/marksy/blob/86b9fd3e4f67f7d8037a6968d04b33b60a179d3b/src/components.js#L38
I tried console.logging the error, and discovered that the compiler is throwing a reference error for hi
being undefined.
To try to work around this issue, I tried different ways of getting the curly braces to not be evaluated as though I'm in JSX. All of them have failed for different reasons:
compile("<Test>{`{hi}`}</Test>")
// compiler treats `{hi}` as a code block
compile("<Test>{'{hi}'}</Test>")
// SyntaxError: unknown: Unexpected character '‘' (1:7)
// > 1 | <Test>{‘{hi}’}</Test>
compile("<Test>{\"{hi}\"}</Test>")
// SyntaxError: unknown: Unexpected character '“' (1:7)
// > 1 | <Test>{“{hi}”}</Test>
Interestingly, this is also an issue for some built-in elements, but not all:
compile("<p>{hi}</p>") // ReferenceError
compile("<h1>{hi}</h1>") // ReferenceError
compile("<div>{hi}</div>") // ReferenceError
compile("<a>{hi}</a>") // this works
compile("<span>{hi}</span>") // this works
I can get around this issue for now by passing my string as a prop to the component rather than trying to make it a child. But this behavior feels like a bug to me. Any idea what's happening?
Thanks!
Here's another one!
compile("<Test>{\`{hi}\`}</Test>")
// SyntaxError: unknown: Unexpected token (1:8)
// > 1 | <Test>{{{0}}}</Test>
Any updates on this?
@mmmaaatttttt @Stanley-Jovel Hi there :) Sorry I am late on responses, but just got out of paternity leave and back to work.
compile("<Test>{\`{hi}\`}</Test>")
That does not really make any sense because hi
is an undefined variable. Not sure what you expect the output should be? It would be like writing:
function Comp () {
return <div>{hi}</div>
}
There is no reference to hi
anywhere.... maybe you could explain a bit more what you are trying to achieve? Might be a different way :)
Hey @christianalfoni,
Congratulations! I can't speak to @Stanley-Jovel, but I'm just trying to escape the curly braces so that the children just get evaluated as a string.
@mmmaaatttttt Hi again and thanks :)
I would suggest this is what you want?
compile("<Test>{'hi'}</Test>")
It is like:
<Test>{"hi"}</Test>
While above example looks like this:
<Test>"{hi}"</Test>
That does not work :) Or you could do:
<Test>{"{hi}"}</Test>
If you want to include curlies in the string :)
Do I understand this correctly?
Hey @christianalfoni !
Sorry for the extreme delay. I ended up using a workaround by passing down a prop rather than using the children, but I'm circling back to this issue now.
Unfortunately, I don't think the fix you suggested does the trick, because the behavior of the compiler is a little strange when curly braces are in the string.
The issue comes up even with a built-in p-tag. Check it out (this is the behavior I see using 6.0.3):
import marksy from "marksy/components";
import React, { createElement } from "react";
// make a minimal compiler
const compile = marksy({
createElement
});
compile("<p>'hi'</p>"); // the tree is an array with one element, as expected
compile("<p>{'hi'}</p>"); // the tree is empty (?!)
compile("<p>'{hi}'</p>"); // the tree is empty again (?!?!)
compile("<p>'awelf{hi'</p>"); // the tree is empty again (?!?!?!)
compile("<p>'awelf}hi'</p>"); // the tree has one element
It seems like the presence of a single curly brace inside of a string inside of the p tag is enough to throw off the compilation. Also, this behavior doesn't exist for all elements; a
tags, for example, behave as you'd expect.