Skip to content

Commit 225b9ce

Browse files
committed
Always treat _createMdxContent as a JSX component
If the user provides a `wrapper` component, `_createMdxContent` was treated as a JSX component. Otherwise it was invoked as a function. Because `_createMdxContent` uses a hook, this hooks becomes part of the `MDXContent` component conditionally. This breaks React’s rule of hooks. Closes #2444
1 parent 8f754f7 commit 225b9ce

File tree

7 files changed

+52
-46
lines changed

7 files changed

+52
-46
lines changed

docs/docs/using-mdx.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export default function MDXContent(props = {}) {
7878
const {wrapper: MDXLayout} = props.components || {}
7979
return MDXLayout
8080
? _jsx(MDXLayout, {...props, children: _jsx(_createMdxContent, {...props})})
81-
: _createMdxContent(props)
81+
: _jsx(_createMdxContent, {...props})
8282
}
8383
```
8484

docs/guides/injecting-components.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ changes when `providerImportSource: 'xxx'` is passed:
7878
+ const {wrapper: MDXLayout} = {..._provideComponents(), ...props.components}
7979
return MDXLayout
8080
? _jsx(MDXLayout, {...props, children: _jsx(_createMdxContent, {...props})})
81-
: _createMdxContent(props)
81+
: _jsx(_createMdxContent, {...props})
8282
```
8383

8484
Observe that components have defaults (such as that `h1` will use `'h1'`) and

packages/mdx/lib/plugin/recma-document.js

+26-28
Original file line numberDiff line numberDiff line change
@@ -559,8 +559,8 @@ export function recmaDocument(options) {
559559
* Functions.
560560
*/
561561
function createMdxContent(content, outputFormat, hasInternalLayout) {
562-
/** @type {JSXElement} */
563-
const element = {
562+
/** @type {Expression} */
563+
let result = {
564564
type: 'JSXElement',
565565
openingElement: {
566566
type: 'JSXOpeningElement',
@@ -577,39 +577,15 @@ export function recmaDocument(options) {
577577
type: 'JSXClosingElement',
578578
name: {type: 'JSXIdentifier', name: 'MDXLayout'}
579579
},
580-
children: [
581-
{
582-
type: 'JSXElement',
583-
openingElement: {
584-
type: 'JSXOpeningElement',
585-
name: {type: 'JSXIdentifier', name: '_createMdxContent'},
586-
attributes: [
587-
{
588-
type: 'JSXSpreadAttribute',
589-
argument: {type: 'Identifier', name: 'props'}
590-
}
591-
],
592-
selfClosing: true
593-
},
594-
closingElement: null,
595-
children: []
596-
}
597-
]
580+
children: [createMdxContentElement()]
598581
}
599582

600-
let result = /** @type {Expression} */ (element)
601-
602583
if (!hasInternalLayout) {
603584
result = {
604585
type: 'ConditionalExpression',
605586
test: {type: 'Identifier', name: 'MDXLayout'},
606587
consequent: result,
607-
alternate: {
608-
type: 'CallExpression',
609-
callee: {type: 'Identifier', name: '_createMdxContent'},
610-
arguments: [{type: 'Identifier', name: 'props'}],
611-
optional: false
612-
}
588+
alternate: createMdxContentElement()
613589
}
614590
}
615591

@@ -693,6 +669,28 @@ export function recmaDocument(options) {
693669
}
694670
}
695671

672+
/**
673+
* @returns {JSXElement}
674+
*/
675+
function createMdxContentElement() {
676+
return {
677+
type: 'JSXElement',
678+
openingElement: {
679+
type: 'JSXOpeningElement',
680+
name: {type: 'JSXIdentifier', name: '_createMdxContent'},
681+
attributes: [
682+
{
683+
type: 'JSXSpreadAttribute',
684+
argument: {type: 'Identifier', name: 'props'}
685+
}
686+
],
687+
selfClosing: true
688+
},
689+
closingElement: null,
690+
children: []
691+
}
692+
}
693+
696694
/**
697695
* @param {Program} tree
698696
* @param {string} name

packages/mdx/readme.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ export default function MDXContent(props = {}) {
119119
const {wrapper: MDXLayout} = props.components || {}
120120
return MDXLayout
121121
? _jsx(MDXLayout, {...props, children: _jsx(_createMdxContent, {...props})})
122-
: _createMdxContent(props)
122+
: _jsx(_createMdxContent, {...props})
123123
}
124124
```
125125

@@ -678,7 +678,7 @@ Configuration for `createProcessor` (TypeScript type).
678678
- children: _jsx(_createMdxContent, props)
679679
- })
680680
+ ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout>
681-
: _createMdxContent(props)
681+
: _jsx(_createMdxContent, {...props})
682682
}
683683
}
684684
```
@@ -897,8 +897,8 @@ Configuration for `createProcessor` (TypeScript type).
897897
+ }
898898

899899
return MDXLayout
900-
? _jsx(MDXLayout, {...props, children: _jsx(_createMdxContent, {})})
901-
: _createMdxContent()
900+
? _jsx(MDXLayout, {...props, children: _jsx(_createMdxContent, {...props})})
901+
: _jsx(_createMdxContent, {...props})
902902
```
903903

904904
</details>

packages/mdx/test/compile.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -746,7 +746,7 @@ test('@mdx-js/mdx: compile', async function (t) {
746746
assert.deepEqual(
747747
// @ts-expect-error: `_source` is untyped but exists.
748748
developmentSourceNode._source,
749-
{fileName: 'path/to/file.js', lineNumber: 1, columnNumber: 1}
749+
{fileName: 'path/to/file.js'}
750750
)
751751
}
752752
)
@@ -1166,7 +1166,7 @@ test('@mdx-js/mdx: compile (JSX)', async function (t) {
11661166
'}',
11671167
'export default function MDXContent(props = {}) {',
11681168
' const {wrapper: MDXLayout} = props.components || ({});',
1169-
' return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout> : _createMdxContent(props);',
1169+
' return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout> : <_createMdxContent {...props} />;',
11701170
'}',
11711171
''
11721172
].join('\n')
@@ -1184,7 +1184,7 @@ test('@mdx-js/mdx: compile (JSX)', async function (t) {
11841184
'}',
11851185
'export default function MDXContent(props = {}) {',
11861186
' const {wrapper: MDXLayout} = props.components || ({});',
1187-
' return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout> : _createMdxContent(props);',
1187+
' return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout> : <_createMdxContent {...props} />;',
11881188
'}',
11891189
''
11901190
].join('\n')
@@ -1207,7 +1207,7 @@ test('@mdx-js/mdx: compile (JSX)', async function (t) {
12071207
'}',
12081208
'export default function MDXContent(props = {}) {',
12091209
' const {wrapper: MDXLayout} = props.components || ({});',
1210-
' return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout> : _createMdxContent(props);',
1210+
' return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout> : <_createMdxContent {...props} />;',
12111211
'}',
12121212
'function _missingMdxReference(id, component) {',
12131213
' throw new Error("Expected " + (component ? "component" : "object") + " `" + id + "` to be defined: you likely forgot to import, pass, or provide it.");',
@@ -1230,7 +1230,7 @@ test('@mdx-js/mdx: compile (JSX)', async function (t) {
12301230
'}',
12311231
'export default function MDXContent(props = {}) {',
12321232
' const {wrapper: MDXLayout} = props.components || ({});',
1233-
' return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout> : _createMdxContent(props);',
1233+
' return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout> : <_createMdxContent {...props} />;',
12341234
'}',
12351235
''
12361236
].join('\n')
@@ -1254,7 +1254,7 @@ test('@mdx-js/mdx: compile (JSX)', async function (t) {
12541254
'}',
12551255
'export default function MDXContent(props = {}) {',
12561256
' const {wrapper: MDXLayout} = props.components || ({});',
1257-
' return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout> : _createMdxContent(props);',
1257+
' return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout> : <_createMdxContent {...props} />;',
12581258
'}',
12591259
''
12601260
].join('\n')
@@ -1277,7 +1277,7 @@ test('@mdx-js/mdx: compile (JSX)', async function (t) {
12771277
'}',
12781278
'export default function MDXContent(props = {}) {',
12791279
' const {wrapper: MDXLayout} = props.components || ({});',
1280-
' return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout> : _createMdxContent(props);',
1280+
' return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout> : <_createMdxContent {...props} />;',
12811281
'}',
12821282
''
12831283
].join('\n')
@@ -1343,7 +1343,7 @@ test('@mdx-js/mdx: compile (JSX)', async function (t) {
13431343
' ..._provideComponents(),',
13441344
' ...props.components',
13451345
' };',
1346-
' return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout> : _createMdxContent(props);',
1346+
' return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout> : <_createMdxContent {...props} />;',
13471347
'}',
13481348
''
13491349
].join('\n')

packages/mdx/test/syntax.js

+11-3
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,9 @@ test('@mdx-js/mdx: syntax: MDX (JSX)', async function (t) {
662662
' children: _jsx(_createMdxContent, {',
663663
' ...props',
664664
' })',
665-
' }) : _createMdxContent(props);',
665+
' }) : _jsx(_createMdxContent, {',
666+
' ...props',
667+
' });',
666668
'}',
667669
''
668670
].join('\n')
@@ -890,7 +892,11 @@ test('@mdx-js/mdx: syntax: MDX (ESM)', async function (t) {
890892
' }, this)',
891893
' }, undefined, false, {',
892894
' fileName: "path/to/file.js"',
893-
' }, this) : _createMdxContent(props);',
895+
' }, this) : _jsxDEV(_createMdxContent, {',
896+
' ...props',
897+
' }, undefined, false, {',
898+
' fileName: "path/to/file.js"',
899+
' }, this);',
894900
'}',
895901
'function _missingMdxReference(id, component, place) {',
896902
' throw new Error("Expected " + (component ? "component" : "object") + " `" + id + "` to be defined: you likely forgot to import, pass, or provide it." + (place ? "\\nIt’s referenced in your code at `" + place + "` in `path/to/file.js`" : ""));',
@@ -924,7 +930,9 @@ test('@mdx-js/mdx: syntax: MDX (ESM)', async function (t) {
924930
' children: _jsx(_createMdxContent, {',
925931
' ...props',
926932
' })',
927-
' }) : _createMdxContent(props);',
933+
' }) : _jsx(_createMdxContent, {',
934+
' ...props',
935+
' });',
928936
'}',
929937
'return {',
930938
' default: MDXContent',

packages/rollup/test/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ test('@mdx-js/rollup', async function (t) {
4141
// Source map.
4242
assert.equal(
4343
chunk.map?.mappings,
44-
';;AAAO,SAAA,OAAA,GAAA;;AAA8B,IAAA,QAAA,EAAA,QAAA;;;;;;;;;AAEnC,IAAA,QAAA,EAAA,CAAA,SAAA,EAAAA,GAAA,CAAA,OAAA,EAAA,EAAA,CAAA,CAAA;;;;;;;;;;;;;;;'
44+
';;AAAO,SAAA,OAAA,GAAA;;AAA8B,IAAA,QAAA,EAAA,QAAA;;;;;;;;;AAEnC,IAAA,QAAA,EAAA,CAAA,SAAA,EAAAA,GAAA,CAAA,OAAA,EAAA,EAAA,CAAA,CAAA;;;;;;;;;;;;;;;;;'
4545
)
4646

4747
await fs.writeFile(jsUrl, chunk.code)

0 commit comments

Comments
 (0)