有没有办法访问React组件的子组件?

时间:2017-11-30 00:33:49

标签: reactjs higher-order-components

所以我知道您可以使用<v-btn fab fixed bottom right>...</v-btn> <v-btn fab fixed bottom right style="bottom: 90px">...</v-btn>

访问组件的子级
this.props.children

如果我对Bob和Sally感兴趣,那会很棒,但如果我想与组成<MyComponent> <span>Bob</span> <span>Sally</span> </MyComponent> 的组件(即MyComponentSubcomp1进行互动,该怎么办?下文)?

Subcomp2

使用案例

我正在尝试创建一个更高阶的组件来管理包装组件的子组件的选项卡索引(粗略选项卡索引:https://www.w3.org/TR/wai-aria-practices/#kbd_roving_tabindex),所以如果我这样做会很棒可以获取包装组件的引用并按类型过滤它的子组件。

到目前为止,唯一可行的方法是让每个组件为每个组件的子组件存储一个参考,但这是乏味的,有点挫败了HOC的目的。是否有通用的方法来访问这些子组件?

我尝试做的一个粗略的例子:

render: function() {
  return (
    <div className="my-comp">
      <Subcomp1 />
      <Subcomp2 />
    </div>
  );
},

1 个答案:

答案 0 :(得分:2)

不需要在HOC中进行tabIndex操作,而是可以在呈现所有HOC的父组件中完成。因为您只需要确定单击哪个子组件并调整父组件上的选定状态。然后可以将所选状态传播回子组件,子组件将其索引与所选索引进行比较,并相应地分配tabIndex

您可以通过传递onClick事件处理程序来发送相应的道具以确定是否选择了当前的ComposedComponent。然后在您的子组件中,您可以使用tabIndex访问this.props.tabIndex并将您的父div渲染为

<div tabIndex={this.props.tabIndex}> </div>

下面的代码几乎就像伪代码一样。如果您认为这不能解决您的要求,您可以尝试通过此链接由杰出开发人员制定的Tab示例CODEPEN EXAMPLE

const HOC = (ComposedComponent) => {
  return class extends React.Component {
    render (
      <ComposedComponent 
        tabIndex={this.props.selected === this.props.index ? "0" : "-1"}
        {...this.props} 
      />
    )
  }
}

class Parent extends React.Component {
  state = {
    selected: 0
  }

  // Set the current selection based on the currentSelection argument
  // that is bound to the function as it is sent along to Props
  adjustTabIndices = (currentSelection) => (event) => {
    this.setState({selection: currentSelection})
  }

  render {
    return (
      <div>
        {
          // These are your various MenuItem components that
          // you want to compose using HOC
          [MenuItem1, MenuItem2, MenuItem3].map(index => {
            const MenuItem = HOC(MenuItem1);
            return (
              <MenuItem
                key={index}
                onClick={this.adjustTabIndices(index)}
                selection={this.state.selected}
                index={index}
              />
            )
          })
        }       
      </div>
    )
  }
}