Gileno
Gileno

Reputation: 106

React: How to get children as string?

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

Answers (2)

user1267177
user1267177

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

Marcilio Leite
Marcilio Leite

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

Related Questions