JsonMarkup React Component

a Component which allows you to write arbitrary JSON code in your CMS and have it display as HTML. The goal is to be a less-dangerous replacement for `dangerouslySetInnerHTML`

by pmn4

HTML

<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<div id="container"></div>

CSS

pre {
  margin-left: 10px;
  border-left: 3px solid #ccc;
  padding: 10px;
  background: #eee;
  position: relative;
}
pre:after {
  content: "JSON Markup";
  position: absolute;
  top: 2px;
  right: 2px;
  color: #aaa;
  font-size: 60%;
}
.rendered-html {
  margin-left: 10px;
  border-left: 3px solid #cdc;
  padding: 10px;
  background: #efe;
  position: relative;
}
.rendered-html:after {
  content: "Rendered HTML";
  position: absolute;
  top: 2px;
  right: 2px;
  color: #aba;
  font-size: 60%;
}
hr {
  margin: 50px 20px;
}

Babel + JSX

// just a string
const stringMarkup = "a simple string";
// two strings with specific tags
const simpleObjectMarkup = {
  h1: "JSON Markup",
  h2: "later dangerouslySetInnerHTML!"
};
// 
const objectMarkup = {
  h1: {
    style: { color: "navyblue" },
    children: "JSON Markup"
  },
  h2: {
    style: { color: "red" },
    children: [
      { span: "✌️ " },
      { code: "dangerouslySetInnerHTML!" }
    ]
  }
};

const markups = {
	stringMarkup,
  simpleObjectMarkup,
  objectMarkup
};


/////////////////////////////////
/////////////////////////////////
//                             //
//                             //
//   copy/pasted from github   //
//                             //
//                             //
/////////////////////////////////
/////////////////////////////////

class JsonMarkup extends React.Component {
  // definition can be:
  //   1. a string (which get printed)
  //   2. an array, whose elements are each rendered through the same process
  //   3. an object, with the special key `children`
  //     a. children will be rendered in a similar style to 1 & 2
  //     b. all other key/values become the props of the element
  renderHtmlElement(TagName, definition, key) {
    let elementContent, children;
    const props = {};

    if (_.isObject(definition) && !_.isArray(definition)) {
      // when our Babel supports more destructuring, replace these lines with:
      // ({ children, ...props }) = definition;
      ({ children } = definition);
      _.extend(props, definition);
      // remove children key so it's not set as a prop on `TagName`
      delete props.children;
    } else {
      children = definition;
    }

    return (
      <TagName {...props} key={key}>
        {this.renderContent(children)}
      </TagName>
    );
  }

  // definitions is an object
  renderHtmlFromObject(definitions, key) {
    if (!definitions) { return; }

    // iterate over key value pairs (usually only one) creating elements
    return...