我应该如何以惯用的 React 方式访问自定义 HTML 组件的生成子项?

Posted

技术标签:

【中文标题】我应该如何以惯用的 React 方式访问自定义 HTML 组件的生成子项?【英文标题】:How should I access generated children of a custom HTML component in an idiomatic React way? 【发布时间】:2020-02-01 03:16:12 【问题描述】:

我正在尝试使用自定义 html 组件创建一个搜索栏,用于预测文本输入。这个组件的构建方式,它会生成几个纯 HTML 子级,我需要对其进行操作以获得完整的功能。具体来说,当用户按下 Escape 或 Enter 键时,我需要对其中一个生成的元素执行模糊操作。

我在自定义组件上使用 ref 并在 ref 上调用 getElementsByClassName 让它工作,但使用 getElementsByClassName 似乎不是最好的解决方案。它穿透虚拟,在测试时有奇怪的副作用。

这是正在渲染的组件的 sn-p:

<predictive-input id='header-search-bar-input' type='search'
  value=this.state.keywords
  ref=(ref: any) => this.predictiveInput = ref
  onKeyDown=(e: React.KeyboardEvent<any>) => this.handleKeyDown(e)>
</predictive-input>

和 keyDown 处理程序:

private handleKeyDown(e: React.KeyboardEvent<any>) 
    // must access the underlying input element of the kat-predictive-input
    let input: HTMLElement = this.predictiveInput.getElementsByClassName('header-row-text value')[0] as HTMLElement;
    if (e.key === 'Escape') 
        // blur the predictive input when the user presses escape
        input.blur();
     else if (e.key === 'Enter') 
        // commit the search when user presses enter
        input.blur();
        // handles action of making actual search, using search bar contents
        this.commitSearch();
    

该元素呈现两个子元素,一个用于栏本身,一个用于预测下拉菜单。第一个底层的类是'header-row-text'和'value',所以元素被正确选择,但我担心这违反了正确的React风格。

我使用的是 React 16.2,所以只有回调引用可用。我宁愿避免升级,但如果 16.3+ 的解决方案足够引人注目,我可以考虑。

【问题讨论】:

你对predictive-input的内部有任何控制权吗? 这是我公司另一个团队制作的组件,供内部使用。从某种意义上说,我有控制权,因为我可以发出请求,而且我知道它不会在没有通知的情况下被彻底改变,但我不能直接在 React 虚拟 DOM 中访问它。 【参考方案1】:

如果您对输入没有任何控制权,那么我认为这是最好的方法。

这并不理想,但由于您受困于第 3 方组件,因此您只能从可用的方法中进行选择。在这种情况下,您唯一真正的选择是根据其类或其在层次结构中的位置来查找元素。如果包更新,两者都可能会改变,但如果我必须选择哪个更稳定,我会选择className

【讨论】:

以上是关于我应该如何以惯用的 React 方式访问自定义 HTML 组件的生成子项?的主要内容,如果未能解决你的问题,请参考以下文章

React Hooks:确保 useEffect 仅在自定义钩子的数组参数内容更改时运行的惯用方法

仅在第一次以惯用方式和优雅方式呈现组件时执行 react-apollo-hooks useQuery

使用自定义 MarshalJSON() 方法嵌入结构的惯用方式

自定义 UINavigationBar 的最惯用的 iOS5 方式?

如何从 React 中的事件对象访问自定义属性?

如何使用create-react-app以root身份更新自定义GitHub页面