React中的继承反转遍历整个树

时间:2018-07-14 15:10:20

标签: javascript reactjs inheritance inversion

我正在尝试在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标签元素)的函数?

0 个答案:

没有答案