/react-nojsx

A JSON based alternative to JSX. Accepts a simple tree shaped, DOM representing object, and returns a React element with any number children and grandchildren.

Primary LanguageJavaScript

NoJSX

Build Status

A JSON based alternative to JSX. Accepts a simple tree shaped, DOM representing object, and returns a React element. This element could host any number of children and granchildren defined by a children property. The children property is either an HTML (or text) string or an array of children element references.

This mechanism utilizes React.createElement from the React top-level API.

The data object is passed in on construction. The compile method (see example below) returns a single React element. Each element representation in the tree-like object has properties based on the arguments accepted by React.createElement. There are only 3 properties that are important to set in this element object representation: props, type, and children (there is one additional property named escape described below).

By default elements are created using dangerouslySetInnerHTML. This can be overridden by using escape element representation property (see example below).

Installation

$ npm install react-nojsx --save

Example Element Representation

{
  children: 'Hello World.',
  escape: true,
  props: {
    className: 'header header--page'
  },
  type: 'div'
}

Note: escape is optional. Default is false.

Keys

By default NoJSX will generate keys for every element created. This can be overidden by specifying a key as part of the props property, however please ensure the strength of uniqueness is high. NoJSX generates keys based on the index of the element created. This may change in the future. The safest way to override the keys would be to prepend the string value with a prefix.

Example:

{
  children: 'Hello World.',
  escape: true,
  props: {
    className: 'header header--page',
    key: 'foo_123'
  },
  type: 'div'
}

Example Usage

NoJSX could be used in several ways, such as in smaller pieces... or even combined with JSX! Below is an example of potentially the most common use case. More examples coming soon.

import { Component } from 'react';

// using Helmet as an example React element.
import Helmet from 'react-helmet';
import NoJSX from 'react-nojsx';

export default class App extends Component {

  // ...

  render() {
    const {
      title
    } = this.props;

    const templateData = {
      children: [
        {
          props: { title },
          type: Helmet
        },
        {
          children: [
            {
              children: 'Hello Page Header.',
              props: { className: 'header header--page' },
              type: 'h1'
            },
            {
              children: '<strong>Lorem ipsum dolor sit amet</strong>, consectetur adipiscing elit.',
              type: 'p'
            }
          ],
          props: {
            className: 'jumbotron'
          },
          type: 'div'
        },
      ],
      props: { className: 'container container--app' },
      type: 'div'
    };

    const template = new NoJSX(templateData);
    return template.compile();
  }
}

Or you could write it like this (the contents of the render function above):

const {
  title
} = this.props;

const pageHeaderData = {
  children: [
    {
      children: 'Hello Page Header.',
      props: { className: 'header header--page' },
      type: 'h1'
    },
    {
      children: '<strong>Lorem ipsum dolor sit amet</strong>, consectetur adipiscing elit.',
      type: 'p'
    }
  ],
  props: { className: 'jumbotron' },
  type: 'div'
};

const templateData = {
  children: [
    {
      props: { title },
      type: Helmet
    },
    pageHeaderData
  ],
  props: { className: 'container container--app' },
  type: 'div'
};

const template = new NoJSX(templateData);
return template.compile();

Want More?

More documentation and examples coming soon.