引用(Refs)

何时使用 Refs

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

  • 处理焦点、文本选择或媒体控制。
  • 触发强制动画。
  • 集成第三方 DOM 库
  • 如果可以通过声明式实现,则尽量避免使用 refs。
    例如,不要在 Dialog 组件上直接暴露 open() 和 close() 方法,最好传递 isOpen 属性。

为 DOM 元素添加 Ref

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

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

  1. class CustomTextInput extends Nerv.Component {
  2. constructor(props) {
  3. super(props);
  4. this.focus = this.focus.bind(this);
  5. }
  6. focus() {
  7. // 直接使用原生 API 使 text 输入框获得焦点
  8. this.textInput.focus();
  9. }
  10. render() {
  11. // 使用 `ref` 的回调将 text 输入框的 DOM 节点存储到 Nerv
  12. // 实例上(比如 this.textInput)
  13. return (
  14. <div>
  15. <input
  16. type="text"
  17. ref={(input) => { this.textInput = input; }} />
  18. <input
  19. type="button"
  20. value="Focus the text input"
  21. onClick={this.focus}
  22. />
  23. </div>
  24. );
  25. }
  26. }

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

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

为类组件添加 Ref

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

  1. class AutoFocusTextInput extends Nerv.Component {
  2. componentDidMount() {
  3. this.textInput.focusTextInput();
  4. }
  5. render() {
  6. return (
  7. <CustomTextInput
  8. ref={(input) => { this.textInput = input; }} />
  9. );
  10. }
  11. }

String 类型的 Refs

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

  1. class AutoFocusTextInput extends Nerv.Component {
  2. componentDidMount() {
  3. this.refs.textInput.focus(); // 可以通过 this.refs[yourRef] 访问
  4. }
  5. render() {
  6. return (
  7. <input
  8. ref='textInput' />
  9. );
  10. }
  11. }

原文: https://nervjs.github.io/docs/guides/refs.html