Reputation: 106
I am writing documentation for a a couple of components we are building, so the doc (which is also a react component looks like this:
const myDoc = () => (
<div>
<MyComponent title="MyTitle" />
<code className="language-jsx">
{`<MyComponent title="MyTitle" />`}
</code>
</div>
)
See the duplication on MyComponent? So I created the "Code" Component to handle that:
const Code = ({ children }) => (
<div>
{children}
<code>
{children}
</code>
</div>
)
Then MyDoc now is:
const myDoc = () => (
<Code>
<MyComponent title="MyTitle" />
</Code>
)
But since children inside Code is a object, it will not render as string.
Is there a way to achieve this? Or maybe a better solution?
Upvotes: 7
Views: 21686
Reputation:
I was also writing documentation and I also didn't want to change the markdown files every time I change demo. I wanted something like element.innerHTML equivalent.
I stumbled upon this answer and on further searching I found this package called jsxToString in github.
Just mentioning in case someone else is also trying to do documentation and stumbles in this post.
Upvotes: 5
Reputation: 1277
Try this:
const MyComponent = ({
title
}) => (
<div>{title}</div>
)
const MyDoc = () => (
<Code>
<MyComponent title="My title" obj={{obj: {obj: 1}}}>
<MyComponent title="My another component title">
<MyComponent title="My another component title" />
</MyComponent>
</MyComponent>
</Code>
)
const Code = ({
children
}) => (
<div>
{children}
<pre><code>
{JsxString(children)}
</code></pre>
</div>
)
const JsxString = (component, counter = 0) => {
let type = component.type.name;
let props = component.props;
let propsString = "";
for (let key in props) {
if (key !== "children") {
let propValue = props[key];
let value = "";
if (propValue instanceof Object) {
value = `{${JSON.stringify(propValue).replace(/['"]+/g, '')}}`;
} else {
value = `"${propValue}"`;
}
propsString += ` ${key}=${value}`;
}
}
if (props.children) {
counter += 2;
var children = JsxString(props.children, counter);
return `<${type}${propsString}>
${Array(counter).join(" ")} ${children}
${Array(counter).join(" ")}</${type}>`;
}
return `<${type}${propsString} />`;
}
ReactDOM.render(
<MyDoc />,
document.getElementById('container')
);
Upvotes: 1