【问题标题】:Why use Ref when we can use querySelector?当我们可以使用 querySelector 时,为什么还要使用 Ref?
【发布时间】:2020-10-04 04:13:43
【问题描述】:

我是 React 世界的新手,正在学习 Refs。 React 文档说:

Refs 提供了一种访问 DOM 节点或 React 元素的方法 渲染方法。

我认为我们可以用 querySelector 函数做同样的事情。
React 文档提供了一个示例,说明我们如何使用 Refs 来关注输入元素。
这是代码 ->

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

  focusTextInput() {
    // Explicitly focus the text input using the raw DOM API
    // Note: we're accessing "current" to get the DOM node
    this.textInput.current.focus();
  }

  render() {
    // tell React that we want to associate the <input> ref
    // with the `textInput` that we created in the constructor
    return (
      <div>
        <input
          type="text"
          ref={this.textInput} />
        <input
          type="button"
          value="Focus the text input"
          onClick={this.focusTextInput}
        />
      </div>
    );
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

用 querySelector 做同样的事情 ->

class CustomTextInput extends React.Component {
constructor(props) {
    super(props);
    this.textInput = React.createRef();
  }

  focusTextInput = () => {
    const input = document.querySelector("input");
    input.focus();
  };

  render() {
    return (
      <div>
        <input type="text" ref={this.textInput} />
        <button type="button" onClick={this.focusTextInput}>
          Focus the Text Input
        </button>
      </div>
    );
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

【问题讨论】:

  • 假设文档中有多个输入。你怎么知道你的 querySelector 返回了正确的?如果您的组件在同一个视图中多次使用怎么办?
  • @rayhatfield 我们可以将 id 添加到输入中
  • 重要提示:.querySelector --> 返回文档中与指定选择器或选择器组匹配的第一个元素。 .querySelectorAll() --> 返回一个静态(非实时)NodeList,表示与指定选择器组匹配的文档元素列表。
  • querySelector() 在所有 html 元素中搜索以找到目标元素,但使用 ref 您可以直接访问该元素。此外,您要查找的元素可能会发生变化,例如它的cssClass 可能会被删除,您将无法再找到它。
  • 过度简化的原因是 React 会随着状态的变化替换 dom 中的现有元素,尽管它们看起来相同并且具有相同的属性,但它们每次都不是完全相同的元素对象。 React 在后台执行此操作,您应该关注的是状态而不是 dom

标签: javascript html reactjs


【解决方案1】:

由于框架本身已经公开了一种方法来做一些可以通过 vanilla javascript 完成的事情,因此它当然具有额外的优势。我能想到的场景之一是使用 React.forwardRef 可用于:

  • 将引用转发到 DOM 组件
  • 在高阶组件中转发引用

如 React 文档本身所述:

const FancyButton = React.forwardRef((props, ref) => (
  <button ref={ref} className="FancyButton">
    {props.children}
  </button>
));

// You can now get a ref directly to the DOM button:
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;

【讨论】:

    【解决方案2】:

    你不需要 react 或 angular 来进行任何 web 开发,angular 和 react 为我们提供了一个包装器,它将尝试为我们优化可重用组件, 我们使用 react 开发的所有组件都可以通过 web-component 完成,但旧版浏览器不支持。

    我列出了在 React 中使用 ref 的一些好处

    1. 如果您使用服务器端渲染,这将很有帮助,使用 Web API 时要小心,因为它们不适用于服务器端 Ex、文档、Window、localStorage
    2. 你可以轻松地监听对象状态的变化,你没有 一次又一次地维护或查询 DOM,框架将 为你做这件事。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多