Skip to content

Instantly share code, notes, and snippets.

@Olical
Last active August 29, 2015 14:10
Show Gist options
  • Select an option

  • Save Olical/03330e06ed64420bfff5 to your computer and use it in GitHub Desktop.

Select an option

Save Olical/03330e06ed64420bfff5 to your computer and use it in GitHub Desktop.
Compiles an array tree structure into React DOM. Skip JSX, but without being SUPER verbose (will turn into an actual library soon)
var React = require('react');
var _ = require('lodash');
/**
* Compiles an array into a React DOM structure recursively. All segments of the node array are optional.
*
* The array segments can be in any order apart from the node type, that always needs to be first.
*
* Actually works really well, I'd quite like to open source this with CSS selector parsing in the nodeName.
*
* @param {*[]} node Comprised of a string DOM node name, params object and string content or child node(s). The nodes can be more arrays or compiled React elements.
* @return {Object} A react DOM tree built from your data structure recursively.
*/
function compile(node) {
if (_.isArray(node)) {
var nodeName = _.first(node);
var findProp = _.partial(_.find, _.rest(node));
var props = _.mapValues({
attrs: _.isPlainObject,
children: _.isArray,
compiled: React.isValidElement,
text: _.isString
}, findProp);
var child = props.text || props.compiled || _.map(props.children, compile);
return React.createElement(nodeName, props.attrs, child);
}
else {
return node;
}
}
module.exports = compile;
// I BUILT THIS WITH MOCHA AND SHOULD.JS, JUST PASTING IN HERE AS CRAPPY DOCUMENTATION
// WHILST I TURN THIS INTO SOME SORT OF LIBRARY
var compile = require('../../src/utils/compile');
var React = require('react');
var render = function (tree) {
return React.renderToStaticMarkup(compile(tree));
};
describe('compile', function () {
describe('simple text', function () {
it('should handle a type and content', function () {
render(['p', 'text']).should.equal('<p>text</p>');
});
it('should handle a type and nested content', function () {
render(['p', ['text']]).should.equal('<p>text</p>');
});
});
describe('with an attribute', function () {
it('should handle an id attribute', function () {
render(['p', {id: 'f'}, 'text']).should.equal('<p id="f">text</p>');
});
});
describe('nested', function () {
it('should handle nested arrays', function () {
render(['p', [['span', 'text', {key:0}]]]).should.equal('<p><span>text</span></p>');
});
it('should handle pre-compiled values', function () {
var pre = compile(['span', 'text', {key:0}]);
render(['p', [pre]]).should.equal('<p><span>text</span></p>');
});
});
});
@aiba

aiba commented Dec 3, 2014

Copy link
Copy Markdown

I like this. It makes functional DOM creation with React more concise, and reminds me of clojure's hiccup. Did you ever get around to making this into a library?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment