score:18

Accepted answer

a react prop type is just a function, so it can be referenced lazily like this:

function lazyfunction(f) {
    return function () {
        return f.apply(this, arguments);
    };
}

var lazytreetype = lazyfunction(function () { 
    return treetype;
});

var treetype = react.proptypes.shape({
    value: react.proptypes.string.isrequired,
    children: react.proptypes.arrayof(lazytreetype)
})

the rest of the code for a complete working example (also available as a jsfiddle):

function haschildren(tree) {
    return !!(tree.children && tree.children.length);
}

var tree = react.createclass({
    proptypes: {
        tree: treetype
    },
    render: function () {
        return this.renderforest([this.props.tree], '');
    },
    rendertree: function (tree, key) {
        return <li classname="tree" key={key}>
            <div title={key}>{tree.value}</div>
            {haschildren(tree) &&
                this.renderforest(tree.children, key)}
        </li>;
    },
    renderforest: function (trees, key) {
        return <ol>{trees.map(function (tree) {
            return this.rendertree(tree, key + ' | ' + tree.value);
        }.bind(this))}</ol>;
    }
});

var treeoflife = { value: "life", children: [
    {value: "animal", children: [
        {value: "dog"},
        {value: "cat"}
    ]},
    {value: "plant"}
]};

react.render(
    <tree tree={treeoflife}/>,
    document.getelementbyid('tree'));

screenshot of the result:

screenshot of the result

score:0

i created recursive prop types something like this and it worked for me. let me know if it works for you as well. lazytreetype function will be called as many times as there is a sub in the object.

const lazytreetype = () => some_props;
const some_props= proptypes.shape({
  date: proptypes.string,
  updated: proptypes.string,
  name: proptypes.string,
  sub: proptypes.arrayof(lazytreetype),
  type: proptypes.string,
});

const component_proptype = proptypes.shape({
  id: proptypes.string,
  sub: proptypes.arrayof(some_props),
});

score:8

here's another approach, courtesy of jethrolarson on github:

given the recursive component tree

import react from 'react';

const tree = ({treedata}) => (
    <div>
        {treedata.nodename}{' '}
        {treedata.children.map(subtree => (
            <tree treedata={subtree} />
        ))}
    </div>
);

that takes a tree data structure like the one below

                root
                /  \
           child1   child2
          /     \        \
     gchild1   gchild2   gchild3

(as code:

const treedata = {
    nodename: "root",
    children: [
        {
            nodename: "child1",
            children: [
                {nodename: "gchild1"},
                {nodename: "gchild2"},
            ]
        },
        {
            nodename: "child2",
            children: [
                {nodename: "gchild3"},
            ]
        },
    ]
};

),

the proptypes for tree can be defined as:

import proptypes from 'prop-types';

const treedatashape = {
    nodename: proptypes.string.isrequired,
};
treedatashape.children = proptypes.arrayof(proptypes.shape(treedatashape));

tree.proptypes = {
    treedata: proptypes.shape(treedatashape),
};

note how all of the references to treedatashape refer to the same object. defining children after the object is created lets you recursively reference the same object.


Related Query

More Query from same tag