mdx: Bug: working with render props

Isn’t possible to reproduce render props component like that:

import { Foo } from './Foo'

# Hello Foo

<Foo>
  {() => {
    const bar = 'bar'

    return (
      <Bar bar={bar} />
    )
  }}
</Foo>

I noticed that in the MDAST => MDXAST process you just turn HTML into JSX nodes, but in this case the line breaks between const and return is a trade off, because the parse is a Paragraph instead of the same scope of HTML.

So, I was trying to figure out how fix this and I think that what can be a possible solution is create something like a merge between nodes when the HTML node that has the opening tag is invalid (without enclosing tag). I don’t know if this can generate some trade offs or is a solution that fit in all cases. So, I didn’t think yet how this can affect performance, but was the only thing that came in mind in that case 😞

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 1
  • Comments: 18 (8 by maintainers)

Most upvoted comments

Just to give some context to @erquhart’s comment/question:

For the initial MDX implementation I kept in mind a very strict superset of Javascript (or not even JS, as JSX is not JS), the only thing MDX parses are import export and jsx jsx is handled by unified, we convert the html nodes to jsx nodes for consistency. import/export are parsed in the simplest way possible, if the ast node starts with import/export it’s an import/export, if not it’s normal text.

I’ve always thought that writing render props / other JS in MDX documents doesn’t make sense as it introduces unnecessary complexity and there are other ways to handle it, for example as you can use JSX you could move that code into a component and make that component render everything you need.

It’s also a good idea to keep in mind that soon render props will in most cases be replaced by Hooks.

The only case that is interesting to explore deeper is the possibility to write JSX inside of markdown syntax like **<Something />** which is currently not possible. I know @johno has been playing around with this idea for a while though.

So the only reason Pedro’s example doesn’t work is the empty line break between const and return, remark Will parse that as 2 paragraph nodes

As a user, I don’t think MDX should be able to do this. It reduces readability and seems like a maintenance nightmare.

The way I see it, MDX is supposed to be Markdown with occasional embedded JSX. Your example features Markdown with embedded JSX with embedded JavaScript returning JSX with embedded Markdown.

I think the burden of resolving that kind of complexity should fall onto the user. Depending on your use case, you could split these into multiple MDX files, do some voodoo with the components prop etc.

If you have a real-world example where MDX falls short and you would like to share it, please do!

Sorry for the close/open, writing on my phone and hitting the wrong button 😅