Description
Initial checklist
- I read the support docs
- I read the contributing guide
- I agree to follow the code of conduct
- I searched issues and couldn’t find anything (or linked relevant results below)
Affected packages and versions
^2.0.0-rc.2 (#1810)
Link to runnable example
No response
Steps to reproduce
Run the following script:
import { compile } from '@mdx-js/mdx';
const { value } = await compile('hello', { jsx:true })
console.log(value)
The jsx
option is there for readability of the output. The issue applies if it’s either true or false.
Expected behavior
The output doesn’t define a component inside a component. This is a React anti-pattern, because it causes unnecessary rerenders
The following Google search yields some articles that explain why this is a bad idea in React: https://www.google.com/search?q=react+create+component+inside+component. Example article: https://dev.to/borasvm/react-create-component-inside-a-component-456b. The same principles apply to Preact.
Earlier the output was ok:
/*@jsxRuntime automatic @jsxImportSource react*/
function MDXContent(props = {}) {
const _components = Object.assign({
p: "p"
}, props.components), {wrapper: MDXLayout} = _components;
const _content = <><_components.p>{"hello"}</_components.p></>;
return MDXLayout ? <MDXLayout {...props}>{_content}</MDXLayout> : _content;
}
export default MDXContent;
Alternative output that’s also ok for React/Preact, although I recall it’s troublesome for some frameworks:
/*@jsxRuntime automatic @jsxImportSource react*/
import { Fragment as _Fragment } from 'react/jsx-runtime.js'
function MDXContent(props = {}) {
const _components = Object.assign({
p: "p"
}, props.components), {wrapper: MDXLayout = _Fragment} = _components;
return <MDXLayout><_components.p>{"hello"}</_components.p></MDXLayout>;
}
export default MDXContent;
Actual behavior
The output does define a component inside a component, which causes unnecessary rerenders.
/*@jsxRuntime automatic @jsxImportSource react*/
function MDXContent(props = {}) {
const {wrapper: MDXLayout} = props.components || ({});
return MDXLayout ? <MDXLayout {...props}><_createMdxContent /></MDXLayout> : _createMdxContent();
function _createMdxContent() {
const _components = Object.assign({
p: "p"
}, props.components);
return <_components.p>{"hello"}</_components.p>;
}
}
export default MDXContent;
Runtime
Node v16
Package manager
npm v8
OS
Linux
Build and bundle tools
Other (please specify in steps to reproduce)