Подтвердить что ты не робот

Можно ли рекурсивно определить тип поддержки React?

Предположим, что мы определяем класс React, который будет отображать дерево.

React.createClass({
    propTypes: {
        tree: treeType
    },
    render: function () {
        // ...
    }
});

Здесь определение treeType, которое, очевидно, не работает, но, надеюсь, иллюстрирует то, что я пытаюсь выразить.

var treeType = React.PropTypes.shape({
    value: React.PropTypes.string,
    children: React.PropTypes.arrayOf(treeType)
})

Есть ли способ позволить типу ссылаться на себя лениво, чтобы это могло работать?

4b9b3361

Ответ 1

A Тип React prop - это просто функция, поэтому на нее можно ссылаться лениво:

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)
})

Остальная часть кода для полного рабочего примера (также доступна как 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