假设我们正在定义一个将显示树的React类。
React.createClass({
propTypes: {
tree: treeType
},
render: function () {
// ...
}
});
这里的treeType
定义显然不起作用,但希望说明我试图表达的内容。
var treeType = React.PropTypes.shape({
value: React.PropTypes.string,
children: React.PropTypes.arrayOf(treeType)
})
有没有办法让这种类型懒惰地引用自己,这样才能起作用?
答案 0 :(得分:16)
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)
})
完整工作示例的其余代码(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'));
结果截图:
答案 1 :(得分:2)
这是另一种方法,由jethrolarson on GitHub提供:
给出递归组件Tree
import React from 'react';
const Tree = ({treeData}) => (
<div>
{treeData.nodeName}{' '}
{treeData.children.map(subTree => (
<Tree treeData={subTree} />
))}
</div>
);
采用如下所示的树数据结构
Root
/ \
Child1 Child2
/ \ \
GChild1 GChild2 GChild3
(作为代码:
const treeData = {
nodeName: "Root",
children: [
{
nodeName: "Child1",
children: [
{nodeName: "GChild1"},
{nodeName: "GChild2"},
]
},
{
nodeName: "Child2",
children: [
{nodeName: "GChild3"},
]
},
]
};
),
propTypes
的{{1}}可以定义为:
Tree
请注意,对import PropTypes from 'prop-types';
const treeDataShape = {
nodeName: PropTypes.string.isRequired,
};
treeDataShape.children = PropTypes.arrayOf(PropTypes.shape(treeDataShape));
Tree.propTypes = {
treeData: PropTypes.shape(treeDataShape),
};
的所有引用如何引用同一对象。创建对象后定义treeDataShape
,可以递归引用同一对象。
答案 2 :(得分:0)
我创建了像这样的递归道具类型,它对我有用。让我知道它是否也适用于您。 lazyTreeType函数的调用次数将与对象中存在子项的次数相同。
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),
});