Can A React Prop Type Be Defined Recursively?
Suppose we're defining a React class that will display a tree. React.createClass({ propTypes: { tree: treeType }, render: function () { // ... } });
Solution 1:
A React prop type is just a function, so it can be referenced lazily like this:
functionlazyFunction(f) {
returnfunction () {
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):
functionhasChildren(tree) {
return !!(tree.children && tree.children.length);
}
varTree = React.createClass({
propTypes: {
tree: treeType
},
render: function () {
returnthis.renderForest([this.props.tree], '');
},
renderTree: function (tree, key) {
return<liclassName="tree"key={key}><divtitle={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(
<Treetree={treeOfLife}/>,
document.getElementById('tree'));
Screenshot of the result:
Solution 2:
Here's another approach, courtesy of jethrolarson on GitHub:
Given the recursive component Tree
importReactfrom'react';
constTree = ({treeData}) => (
<div>
{treeData.nodeName}{' '}
{treeData.children.map(subTree => (
<TreetreeData={subTree} />
))}
</div>
);
that takes a tree data structure like the one below
Root
/ \
Child1 Child2
/ \ \
GChild1 GChild2 GChild3
(as code:
consttreeData= {
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.
Solution 3:
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),
});
Post a Comment for "Can A React Prop Type Be Defined Recursively?"