React-refs

302 阅读3分钟

React-refs

React的核心思想是每次对于界面state的改动,都会重新渲染整个Virtual DOM,然后新老的两个Virtual DOM 进行diff(协调算法),对比出变化的地方,然后通过render渲染到实际的UI界面

  • Refs:为我们提供了一种绕过状态更新和重新渲染访问元素的方法(获取某个元素的实例),但不能作为props 和 state 的替代方法
  • 在项目开发中,如果我们可以使用 声明式 或 提升 state 所在的组件层级(状态提升) 的方法来更新组件,最好不要使用 refs
  • Refs使用场景: 1. 管理焦点(如文本选择)或处理表单数据: 因为非受控组件将真实数据储存在 DOM 节点中,所以再使用非受控组件时,有时候反而更容易同时集成 React 和非 React 代码。如果你不介意代码美观性,并且希望快速编写代码,使用非受控组件往往可以减少你的代码量。否则,你应该使用受控组件 2. 媒体播放: 基于 React 的音乐或视频播放器可以利用 Refs 来管理其当前状态(播放/暂停),或管理播放进度等。这些更新不需要进行状态管理。 3. 触发强制动画: 如果要在元素上触发过强制动画时,可以使用 Refs 来执行此操作。
  • Refs使用方式
    1. 通过 createRef 实现
    export default class Hello extends React.Component {
        constructor(props) {
            super(props);
            <!-- 创建 ref 存储 textRef DOM 元素 -->
            this.textRef = React.createRef(); 
        }
        render() {
            <!-- 把 <input> ref 关联到构造器里创建的 textRef 上 -->
            return <input ref={this.textRef} />
        }
    }	
    
    1. 回调 Refs
    export default class Hello extends React.Component {
        constructor(props) {
            super(props);
            this.textRef = null; // 创建 ref 为 null
        }
        componentDidMount() {
            // 注意:这里没有使用 "current" 
            // 直接使用原生 API 使 text 输入框获得焦点
            this.textRef.focus(); 
        }
        render() {
            // 把 <input> ref 关联到构造器里创建的 textRef 上
            return <input ref={node => this.textRef = node} />
        }
    }
    
    1. 通过 stringRef 实现
    export default class Hello extends React.Component {
        constructor(props) {
            super(props);
        }
        componentDidMount() {
            // 通过 this.refs 调用
            // 直接使用原生 API 使 text 输入框获得焦点
            this.refs.textRef.focus(); 
        }
        render() {
            // 把 <input> ref 关联到构造器里创建的 textRef 上
            return <input ref='textRef' />
        }
    }
    
    尽管字符串 stringRef 使用更方便,但是它有一些缺点,因此严格模式使用 stringRef 会报警告。官方推荐采用回调 Refs。

注意:

  • 当 ref 属性被用于一个普通的 HTML 元素时,React.createRef() 将接收底层 DOM 元素作为它的 current 属性以创建 ref ,我们可以通过 Refs 访问 DOM 元素属性
  • 当 ref 属性被用于一个自定义 class 组件时,ref 对象将接收该组件已挂载的实例作为它的 current,与 ref 用于 HTML 元素不同的是,我们能够通过 ref 访问该组件的props,state,方法以及它的整个原型
  • ref 是为了获取某个节点是实例,所以 你不能在函数式组件上使用 ref 属性,因为它们没有实例
  • 推荐使用 回调形式的 refs, stringRef 将会废弃(严格模式下使用会报警告),React.createRef() API 是 React v16.3 引入的更新