Angenommen, wir definieren eine React-Klasse, die einen Baum anzeigt.

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

Hier ist eine Definition von treeType, die offensichtlich nicht funktioniert, aber hoffentlich veranschaulicht, was ich auszudrücken versuche.

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

Gibt es eine Möglichkeit, den Typ träge auf sich selbst verweisen zu lassen, damit dies funktionieren kann?

17
Chris Martin 18 Aug. 2015 im 06:58

3 Antworten

Beste Antwort

Ein React-Requisitentyp ist nur eine Funktion, daher kann er träge wie folgt referenziert werden:

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

Der Rest des Codes für ein vollständiges Arbeitsbeispiel (auch als jsfiddle verfügbar):

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 des Ergebnisses:

Screenshot of the result

17
Sean Vieira 28 Dez. 2015 im 19:22

Ich habe so etwas wie rekursive Requisitentypen erstellt und es hat bei mir funktioniert. Lassen Sie mich wissen, ob es auch bei Ihnen funktioniert. Die Funktion lazyTreeType wird so oft aufgerufen, wie sich ein Sub im Objekt befindet.

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),
});
0
Yogesh Devgun 25 Okt. 2019 im 09:59

Hier ist ein weiterer Ansatz mit freundlicher Genehmigung von jethrolarson auf GitHub:

Angesichts der rekursiven Komponente Tree

import React from 'react';

const Tree = ({treeData}) => (
    <div>
        {treeData.nodeName}{' '}
        {treeData.children.map(subTree => (
            <Tree treeData={subTree} />
        ))}
    </div>
);

Das erfordert eine Baumdatenstruktur wie die folgende

                Root
                /  \
           Child1   Child2
          /     \        \
     GChild1   GChild2   GChild3

(als Code:

const treeData = {
    nodeName: "Root",
    children: [
        {
            nodeName: "Child1",
            children: [
                {nodeName: "GChild1"},
                {nodeName: "GChild2"},
            ]
        },
        {
            nodeName: "Child2",
            children: [
                {nodeName: "GChild3"},
            ]
        },
    ]
};

),

Das propTypes für Tree kann wie folgt definiert werden:

import PropTypes from 'prop-types';

const treeDataShape = {
    nodeName: PropTypes.string.isRequired,
};
treeDataShape.children = PropTypes.arrayOf(PropTypes.shape(treeDataShape));

Tree.propTypes = {
    treeData: PropTypes.shape(treeDataShape),
};

Beachten Sie, wie sich alle Verweise auf treeDataShape auf dasselbe Objekt beziehen. Wenn Sie children definieren, nachdem das Objekt erstellt wurde, können Sie rekursiv auf dasselbe Objekt verweisen.

3
user128216 19 Sept. 2018 im 17:48