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?
3 Antworten
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:
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),
});
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.