2

所以我知道您可以通过以下方式访问组件的子级this.props.children

<MyComponent>
  <span>Bob</span>
  <span>Sally</span>
</MyComponent>

如果我对 Bob 和 Sally 感兴趣,这很好,但是如果我想与组成的组件(MyComponent即如下所示)进行交互怎么办?Subcomp1Subcomp2

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

用例

我正在尝试创建一个管理包装组件子组件的选项卡索引(漫游选项卡索引: https ://www.w3.org/TR/wai-aria-practices/#kbd_roving_tabindex)的高阶组件,所以如果我能获得包装组件的引用并按类型过滤它的子组件,那就太好了。

到目前为止,似乎唯一可行的方法是让每个组件为其每个子组件存储一个 ref,但这很乏味并且有点违背 HOC 的目的。有没有通用的方法来访问这些子组件?

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

var HOC = (ComposedComponent) => {

  return React.createClass({

    componentDidMount: function() {
      const subComponents = this.composedComponent.subComponents; // Something like this would be nice

      const menuItems = subComponents.filter(() => {
        // figure out a way to identify components of a certain type
      });

      this.applyRovingTabIndex(menuItems); 
    },

    render: function() {
      return (
        <ComposedComponent
          ref={(c) => { this.composedComponent = c }}
          {...this.props} />
      );
    }

  });  
};
4

1 回答 1

2

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

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

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

下面的代码几乎就像给出一个想法的伪代码。如果您觉得这不能解决您的要求,您可以在此链接CODEPEN 示例中尝试由出色的开发人员编写的 Tab 示例

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>
    )
  }
}
于 2017-11-30T04:13:58.540 回答