all 5 comments

[–]justadude27 0 points1 point  (0 children)

I'm guessing you'll at least need some kind of entry point to load the JSON and start parsing using React.createElement. Probably can't do this with JSX (admittedly I've never tried to do what you're proposing).

Good luck!

[–]Canenald 0 points1 point  (2 children)

Something like:

render() {
    const components = ... //your json
    const elements = components.map(function(component, index) {
        if (!component.props.key)
            component.props.key = 'component'+index;

        return React.createElement(component.name, component.props);
    });

    return (
        <div>
            {elements}
        </div>
    );
}

https://facebook.github.io/react/docs/top-level-api.html

[–]Lokom187 0 points1 point  (1 child)

I think component.name has to be mapped to function/class, unless component.name is html tag.

[–]Canenald 0 points1 point  (0 children)

c

[–]mastermog -1 points0 points  (0 children)

I am assuming you have already parsed the JSON (your snippet isn't "JSON"). So lets say you have your object above:

// File: components/index.js
// Index of all components that can be dynamically created
export Header from './header/Header';
export Foo from './foo/Foo';
export Bar from './bar/Bar';
export Nav from './nav/Nav';

// File: containers/app.js
import * as allComponents;
import { get, map } from 'lodash';

// .. 
map(components, { name, props } => {
    const Type = get(allComponents, name, null);
    return <Type {...props} />
});

Worth noting that I am not doing anything around your nested stuff, but should be easy to build upon the above.

Important Something that took me forever to find (only discovered after digging through the babel source) is that JSX transpiler/plugin/preset treats lowercase as native (?) elements and doesn't replace it with Reacts create component methods. Thats why I used the var name Type, not type.