React/Refs and this DOM

Refs 提供了一种方式,容许咱们访问 DOM 节点或在 render 方法中建立的 React 元素javascript

什么时候使用Refshtml

  • 管理焦点,文本选择或媒体播放。
  • 触发强制动画。
  • 集成第三方 DOM 库。

避免使用 refs 来作任何能够经过声明式实现来完成的事情。(好比:避免在 Dialog 组件里暴露 open() 和 close() 方法,最好传递 isOpen 属性。)java

建立 Refs

Refs 是使用 React.createRef() 建立的,并经过 ref 属性附加到 React 元素。在构造组件时,一般将 Refs 分配给实例属性,以即可以在整个组件中引用它们。node

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    return <div ref={this.myRef} />;
  }
}

访问 Refs

当 ref 被传递给 render 中的元素时,对该节点的引用能够在 ref 的 current 属性中被访问。react

const node = this.myRef.current;

ref 的值根据节点的类型而有所不一样:git

  • 当 ref 属性用于 HTML 元素时,构造函数中使用 React.createRef() 建立的 ref 接收底层 DOM 元素做为其 current 属性。
  • 当 ref 属性用于自定义 class 组件时,ref 对象接收组件的挂载实例做为其 current 属性。
  • 不能在函数组件使用 ref 属性,由于他们没有实例。可是能够在函数组件内部使用 ref 属性,只要它指向一个 DOM 元素或 class 组件

React 会在组件挂载时给 current 属性传入 DOM 元素,并在组件卸载时传入 null 值ref 会在 componentDidMount 或 componentDidUpdate 生命周期钩子触发前更新。 github

将 DOM Refs 暴露给父组件

在极少数状况下,你可能但愿在父组件中引用子节点的 DOM 节点。一般不建议这样作,由于它会打破组件的封装,但它偶尔可用于触发焦点测量子 DOM 节点的大小或位置api

若是你使用 16.3 或更高版本的 React, 这种状况下咱们推荐使用 ref 转发数组

Refs转发浏览器

Ref 转发是一项将 ref 自动地经过组件传递到其一子组件的技巧。对于大多数应用中的组件来讲,这一般不是必需的。但其对某些组件,尤为是可重用的组件库是颇有用的。

Ref 转发是一个可选特性,其容许某些组件接收 ref,并将其向下传递(换句话说,“转发”它)给子组件。

转发 refs 到 DOM 组件

在下面的示例中,FancyButton 使用 React.forwardRef 来获取传递给它的 ref,而后转发到它渲染的 DOM button

 

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

// 你能够直接获取 DOM button 的 ref:
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;

 

这样,使用 FancyButton 的组件能够获取底层 DOM 节点 button 的 ref ,并在必要时访问,就像其直接使用 DOM button 同样。

如下是对上述示例发生状况的逐步解释:

  1. 咱们经过调用 React.createRef 建立了一个 React ref 并将其赋值给 ref 变量。
  2. 咱们经过指定 ref 为 JSX 属性,将其向下传递给 <FancyButton ref={ref}>
  3. React 传递 ref 给 forwardRef 内函数 (props, ref) => ...,做为其第二个参数。
  4. 咱们向下转发该 ref 参数到 <button ref={ref}>,将其指定为 JSX 属性。
  5. 当 ref 挂载完成,ref.current 将指向 <button> DOM 节点。

第二个参数 ref 只在使用 React.forwardRef 定义组件时存在。常规函数和 class 组件不接收 ref 参数,且 props 中也不存在 ref

Ref 转发不只限于 DOM 组件,你也能够转发 refs 到 class 组件实例中。

 

回调 Refs

React 也支持另外一种设置 refs 的方式,称为“回调 refs”。它能助你更精细地控制什么时候 refs 被设置和解除

不一样于传递 createRef() 建立的 ref 属性,你会传递一个函数。这个函数中接受 React 组件实例HTML DOM 元素做为参数,以使它们能在其余地方被存储和访问。

React 将在组件挂载时,会调用 ref 回调函数并传入 DOM 元素,当卸载时调用它并传入 null。在 componentDidMount 或 componentDidUpdate 触发前,React 会保证 refs 必定是最新的。

过期 API:String 类型的 Refs

若是你以前使用过 React,你可能了解过以前的 API 中的 string 类型的 ref 属性,例如 "textInput"。你能够经过 this.refs.textInput 来访问 DOM 节点。咱们不建议使用它,由于 string 类型的 refs 存在 一些问题。它已过期并可能会在将来的版本被移除。

findDOMNode

findDOMNode 是一个访问底层 DOM 节点的应急方案(escape hatch)。在大多数状况下,不推荐使用该方法,由于它会破坏组件的抽象结构。严格模式下该方法已弃用。 

ReactDOM.findDOMNode(component)

若是组件已经被挂载到 DOM 上,此方法会返回浏览器中相应的原生 DOM 元素。此方法对于从 DOM 中读取值颇有用,例如获取表单字段的值或者执行 DOM 检测(performing DOM measurements)。
大多数状况下,你能够绑定一个 ref 到 DOM 节点上,能够彻底避免使用 findDOMNode。

当组件渲染的内容为 null 或 false 时,findDOMNode 也会返回 null。当组件渲染的是字符串时,findDOMNode 返回的是字符串对应的 DOM 节点
从 React 16 开始,组件可能会返回有多个子节点的 fragment,在这种状况下,findDOMNode 会返回第一个非空子节点对应的 DOM 节点。

findDOMNode 只在已挂载的组件上可用(即,已经放置在 DOM 中的组件)。若是你尝试调用未挂载的组件(例如在一个还未建立的组件上调用 render() 中的 findDOMNode())将会引起异常。
nullfalsefindDOMNodenullfindDOMNodefindDOMNodefindDOMNoderender()findDOMNode()

  findDOMNode 不能用于函数组件。

 
ReactDOM.unmountComponentAtNode(container)
从 DOM 中卸载组件,会将其事件处理器(event handlers)和 state 一并清除。若是指定容器上没有对应已挂载的组件,这个函数什么也不会作。若是组件被移除将会返回 true,若是没有组件可被移除将会返回 falsetruefalse
相关文章
相关标签/搜索