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

Inconsistent rendering of children #41

Open
mmmaaatttttt opened this issue Oct 14, 2017 · 6 comments
Open

Inconsistent rendering of children #41

mmmaaatttttt opened this issue Oct 14, 2017 · 6 comments

Comments

@mmmaaatttttt
Copy link

mmmaaatttttt commented Oct 14, 2017

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!

@mmmaaatttttt
Copy link
Author

Here's another one!

compile("<Test>{\`{hi}\`}</Test>")
// SyntaxError: unknown: Unexpected token (1:8)
// > 1 | <Test>{{{0}}}</Test>

@Stanley-Jovel
Copy link

Any updates on this?

@christianalfoni
Copy link
Collaborator

@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 :)

@mmmaaatttttt
Copy link
Author

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.

@christianalfoni
Copy link
Collaborator

christianalfoni commented Nov 6, 2017

@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?

@mmmaaatttttt
Copy link
Author

mmmaaatttttt commented Apr 7, 2018

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants