【问题标题】:How to find focused React component? (like document.activeElement)如何找到专注的 React 组件? (如 document.activeElement)
【发布时间】:2020-03-12 04:23:16
【问题描述】:

如果您有 500 个组件,每个组件都有一个 ref,您将如何找到用户关注的组件?所有带有ref 的组件都是可聚焦的元素,例如<input />、<textarea /> 等。为简单起见,所有refs 都可以从单个顶级组件访问。

如果您的 React 组件具有 classNames,这非常简单 - 但是如果您想找到 document.activeElement 的 ref,是否有某种方法可以实现这一目标而不必求助于 classNames?

为了说明我们没有classNames 的原因,我们通过emotion 使用JSS。仅仅为了这个目的而不得不手动分配一个className 是相当荒谬的。我没有想到任何明显的替代方案。

【问题讨论】:

  • 这是您可以通过onFocus 事件而不是使用参考来实现的吗?你能创建一个代码框吗?
  • 同意 Dennis,您可以使用焦点处理程序来访问事件对象上的任何可用数据并将其存储在您的状态中。

标签: javascript reactjs focus react-dom


【解决方案1】:

这可能是一个很好的自定义钩子用例,该钩子钩入本机 DOM 方法以跟踪焦点事件,然后返回活动元素。这将在每次新元素获得焦点时记录活动元素:

const useActiveElement = () => {
  const [active, setActive] = useState(document.activeElement);
  
  const handleFocusIn = (e) => {
    setActive(document.activeElement);
  }
  
  useEffect(() => {
    document.addEventListener('focusin', handleFocusIn)
    return () => {
      document.removeEventListener('focusin', handleFocusIn)
  };
  }, [])
  
  return active;
}

const App = () => {
  const focusedElement = useActiveElement();
  
  useEffect(() => {
     if (focusedElement) {
       focusedElement.value && console.log(focusedElement.value);
     }
    console.log(focusedElement);
  }, [focusedElement])
  
  return (
    <div>
        <input type="text"/>
        <button>Button</button>
    </div>
  )
}

但是,将这个元素与您的引用关联起来可能会很棘手,因为您需要保留一组要搜索的引用,这可能涉及为每个元素提供自己的 callback ref 以存储在数组或类似的东西中.但是根据元素一旦聚焦后你需要对它做什么,它可能没有必要。例如,我在上面发布的代码将记录输入的值(如果存在)。这将有助于更具体地了解您用于跟踪此数据的用例。

【讨论】:

  • @maracuja-juice 为什么?
  • 一个优雅的解决方案
【解决方案2】:

你想要这样的东西吗,react 为你提供了一个使用 ref

跟踪/聚焦的选项
import React, { Component } from "react";

class App extends Component {

constructor(props) {
    super(props);
    // create a ref to store the textInput DOM element
    this.textInput = React.createRef();
    this.button = React.createRef();
    this.textarea = React.createRef();
    this.focusTextInput = this.focusTextInput.bind(this);
}

focusTextInput() {
    // this.textInput.current.focus();
    this.button.current.focus();
    // this.textarea.current.focus();
}

render() {
    return (
    <div>
        <input type="text" ref={this.textInput} />
        <button ref={this.button}>something</button>
        <textarea ref={this.textarea}></textarea>
        <input
              type="button"
              value="Focus the text input"
              onClick={this.focusTextInput}
        />
    </div>
    );
  }
}

export default App;

您可以获取详细信息here

【讨论】:

    猜你喜欢
    • 2019-12-22
    • 2018-09-16
    • 2014-05-10
    • 1970-01-01
    • 1970-01-01
    • 2020-02-24
    • 1970-01-01
    • 2021-03-19
    • 1970-01-01
    相关资源
    最近更新 更多