Closed brandonweiss closed 6 years ago
Does this clear things up?
import { MDXProvider } from '@mdx-js/tag'
import One from './one.mdx'
import Two from './two.mdx'
import Three from './three.mdx'
import { Title, Subtitle } from './body'
const components = {
h1: Title,
h2: Subtitle,
}
const AppWithoutProvider = () => (
<div>
<One components={components} />
<Two components={components} />
<Three components={components} />
</div>
)
const AppWithProvider = () => (
<MDXProvider components={components}>
<One />
<Two />
<Three />
</MDXProvider>
)
@silvenon Thanks for helping!
🤔 I think this is heading in the right direction, although there are still some things I don’t understand…
What is the components
prop? Is that a React thing? An MDX thing? Does something magical happen with it where it appends components to the end of the component it’s passed into? That doesn’t seem right… but it’s hard to tell because I can't see how components
is being consumed inside the child components?
Oh, is the provider a way of passing the same props to every child component? That seems… dangerous? Couldn't you obliterate some props without realizing it? Does it only work with direct children or all children (children of children)?
If that’s what it does… why is it an MDX Provider? It seems like just a generic tool for passing props to all children? There must be something about it I'm missing that ties it into MDX specifically?
It is a bit magical, yes, but deliberately, for the sake of simplicity of usage.
Let's use this MDX example:
import MyComponent from './my-component'
# Title
<MyComponent />
Lorem ipsum dolor sit amet.
When processed with @mdx-js/loader this basically turns into the following JSX code:
import React from 'react'
import { MDXTag } from '@mdx-js/tag'
import MyComponent from './my-component'
export default ({ components }) => (
<MDXTag name="wrapper" components={components}>
<MDXTag name="h1" components={components}>
Title
</MDXTag>
<MyComponent />
<MDXTag name="p" components={components}>
Lorem ipsum dolor sit amet.
</MDXTag>
</MDXTag>
)
This is what you actually import when you import a MDX file. Notice that the default export takes a components
prop. You can either pass this directly or through context using MDXProvider
, like in my previous example. The name
prop of MDXTag
maps to a component defined in the components
prop. If components
doesn't contain that key, it defaults to that tag name, i. e. "p"
becomes <p>
like in regular Markdown.
OK, I'm starting to get it, I think. So the components
prop is a way of overriding an HTML tag to render a specific component instead. Most probably not to change the tag itself, but to apply some styling to it?
And the MDXProvider is necessary because otherwise there’d be no way to pass the components to the tags inside of an MDX file, because it’s Markdown/MDX (no render function and no props). Correct?
What would happen if you passed something other than a components
prop to the MDXProvider? I guess nothing. There’d be no point in proxying other props because you wouldn’t be able to use them inside of MDX.
So the “Component customization“ section and the “MDXProvider” section of the README are… sort of related? I think one helps understand the other.
Would you be open to me improving those sections of the README?
Most probably not to change the tag itself, but to apply some styling to it?
Yeah. But another example could be to shift all headings. Imagine that you have a MDX file starting with h1
, but in a certain context you need headings to start from h2
. In that case you could push them all by one. But yes, generally you would use it for styling purposes.
And the MDXProvider is necessary
It's optional. It's only useful if you're frequently using the same components
object. That's usually the case for blogs. You can pass components
to each imported MDX file, like I showed in the first example. <One components={components}>
means that every MDXTag
in One
will receive the same components
object.
What would happen if you passed something other than a components prop to the MDXProvider? I guess nothing.
Yep, probably nothing.
Would you be open to me improving those sections of the README?
I'm not a maintainer, but go right ahead! Everybody loves documentation improvements. 👍
I'm closing this as a stale issue. This is the current documentation for MDXProvider
: https://mdxjs.com/getting-started/#mdxprovider, and we're open to improvements.
The section in the README on the
MDXProvider
is very short and seems to assume a lot… I don't know what this is, why it exists, what it’s for, etc. Could someone expand on it?