我正在尝试在React中构建一个HOC,该HOC可以操纵传入参数的树中安装的所有react元素。我使用here中所述的继承反转模式。
在该示例中,操作将包括在foo道具中添加“ PASSED !!”。作为名为 Parent 的组件中每个 Child 元素的值。我有下面的树,其中所有 Child 元素都显示其名称,子元素(如果有的话)和foo prop的值:
const Child = ({ foo }) => <div> Child {foo} </div>
const NestedChild = ({ foo }) => <div> NestedChild {foo} </div>
const ChildWithNested1 = ({ foo, children }) => <div> ChildWithNested1 {foo} {children} </div>
const ChildWithNested2 = ({ foo }) => <div> ChildWithNested2 {foo} <NestedChild /> </div>
class Parent extends Component {
render() {
return (
<div>
<Child />
<ChildWithNested1>
<NestedChild />
</ChildWithNested1>
<ChildWithNested2 />
</div>
);
}
}
目标是将foo属性传递给每个Child元素,甚至是嵌套的元素。我构建了一个简单的HOC来递归遍历树:
const HOC = (component) => {
return class WrappedComponent extends component {
traverseTree = (tree) => {
if (tree.props.children) {
const newChildren = React.Children.map(tree.props.children, (item) => this.traverseTree(item))
const newTree = React.cloneElement(tree, { foo: 'PASSED !!' }, newChildren)
return newTree
}
else if (React.isValidElement(tree)) {
const newProps = Object.assign({}, tree.props, { foo: 'PASSED !!' })
return React.cloneElement(tree, newProps, tree.props.children)
}
else {
return tree
}
}
render() {
return this.traverseTree(super.render())
}
}
}
export default HOC(Parent);
然后我在浏览器中得到以下结果:
Child PASSED !!
ChildWithNested1 PASSED !!
NestedChild PASSED !!
ChildWithNested2 PASSED !!
NestedChild
因此,HOC可以按预期工作,除了第二个 NestedChild 元素(直接在 ChildWithNested2 中调用,因此不包含在 props.children 对象,因此HOC中的 traverseTree 函数无法访问该对象。
所以我的问题是:
是否有可能使HOC到达每个react元素以获得此结果:
Child PASSED !!
ChildWithNested1 PASSED !!
NestedChild PASSED !!
ChildWithNested2 PASSED !!
NestedChild PASSED !!
第二,有没有一种方法可以编写仅修改用户命名的react元素(而不是像div这样的html标签元素)的函数?