引用(Refs)

何时使用 Refs

下面是几个适合使用 refs 的情况:

  1. 处理焦点、文本选择或媒体控制。
  2. 触发强制动画。
  3. 集成第三方 DOM 库
  4. 如果可以通过声明式实现,则尽量避免使用 refs。

例如,不要在 Dialog 组件上直接暴露 open() 和 close() 方法,最好传递 isOpen 属性。

为 DOM 元素添加 Ref

Nerv 支持给任意组件添加特殊属性。ref 属性接受一个回调函数,它在组件被加载或卸载时会立即执行。

当给 HTML 元素添加 ref 属性时,ref 回调接收了底层的 DOM 元素作为参数。例如,下面的代码使用 ref 回调来存储 DOM 节点的引用。

class CustomTextInput extends Nerv.Component {
  constructor(props) {
    super(props);
    this.focus = this.focus.bind(this);
  }

  focus() {
    // 直接使用原生 API 使 text 输入框获得焦点
    this.textInput.focus();
  }

  render() {
    // 使用 `ref` 的回调将 text 输入框的 DOM 节点存储到 Nerv 
    // 实例上(比如 this.textInput)
    return (
      <div>
        <input
          type="text"
          ref={(input) => { this.textInput = input; }} />
        <input
          type="button"
          value="Focus the text input"
          onClick={this.focus}
        />
      </div>
    );
  }
}

Nerv 组件在加载时将 DOM 元素传入 ref 的回调函数,在卸载时则会传入 null。ref 回调会在componentDidMountcomponentDidUpdate 这些生命周期回调之前执行。

为了在类上设置一个属性使用 ref 回调是访问 DOM 元素的常见模式。首先的方法就如上面的例子中一样设置 ref。甚至还有更简短的写法: ref={input => this.textInput = input}

为类组件添加 Ref

当 ref 属性用于使用 class 声明的自定义组件时,ref 的回调接收的是已经加载的 Nerv 实例。例如,如果我们想修改 CustomTextInput 组件,实现它在加载后立即点击的效果:

class AutoFocusTextInput extends Nerv.Component {
  componentDidMount() {
    this.textInput.focusTextInput();
  }

  render() {
    return (
      <CustomTextInput
        ref={(input) => { this.textInput = input; }} />
    );
  }
}

String 类型的 Refs

除了函数类型的 Ref 之外,你还可以通过传入一个字符串,然后通过 this.refs.input 这样的形式访问到你的 Ref。但这个方式不管是 React 还是 Nerv 都是不推荐使用的(新版本的 React 将会被移除)。

class AutoFocusTextInput extends Nerv.Component {
  componentDidMount() {
    this.refs.textInput.focus(); // 可以通过 this.refs[yourRef] 访问
  }

  render() {
    return (
      <input
        ref='textInput' />
    );
  }
}

results matching ""

    No results matching ""