refs绑定在this上和公开DOM refs父组件

refs

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

  focus() {
    // Explicitly focus the text input using the raw DOM API
    this.textInput.focus();
  }

  render() {
    // Use the `ref` callback to store a reference to the text input DOM
    // element in an instance field (for example, this.textInput).
    return (
      <div>
        <input
          type="text"
          ref={(input) => { this.textInput = input; }} />
        <input
          type="button"
          value="Focus the text input"
          onClick={this.focus}
        />
      </div>
    );
  }
}

组件挂载或卸载时,会触发ref回调。例ref={(input) => { this.textInput = input; }},挂载时,this.textInput等于当前input;当卸载时,等于null

公开DOM refs父组件

在极少数情况下,您可能希望从父组件访问子节点的DOM节点。通常不建议这样做,因为它会破坏组件封装,但偶尔也可以用于触发焦点或测量子DOM节点的大小或位置。

虽然可以向子组件添加引用,但这不是一个理想的解决方案,因为您只能获取组件实例而不是DOM节点。此外,这对功能组件无效。

相反,在这种情况下,我们建议在小孩身上露出特殊的支撑。孩子将使用任意名称(例如inputRef)使用函数prop ,并将其作为ref属性附加到DOM节点。这允许父代通过中间的组件将其ref回调传递给孩子的DOM节点。

这适用于类和功能组件。

function CustomTextInput(props) {
  return (
    <div>
      <input ref={props.inputRef} />
    </div>
  );
}

class Parent extends React.Component {
  render() {
    return (
      <CustomTextInput
        inputRef={el => this.inputElement = el}
      />
    );
  }

在上面的例子中,Parent将它的ref回调作为一个inputRef支持传递给CustomTextInput,并将与该CustomTextInput特殊ref属性相同的函数传递给<input>。其结果是,this.inputElementParent将被设置为对应于所述DOM节点<input>中的元素CustomTextInput

即使CustomTextInput是功能组件也是如此。与只能为DOM元素和类组件指定的特殊ref属性不同,常规组件道具没有限制。inputRef

这种模式的另一个好处就是它的作用很大。例如,想象Parent不需要DOM节点,但是渲染的组件Parent(让我们称之为Grandparent)需要访问它。然后我们可以让它Grandparent指定inputRef道具Parent,并将Parent其转发到CustomTextInput:

function CustomTextInput(props) {
  return (
    <div>
      <input ref={props.inputRef} />
    </div>
  );
}

function Parent(props) {
  return (
    <div>
      My input: <CustomTextInput inputRef={props.inputRef} />
    </div>
  );
}


class Grandparent extends React.Component {
  render() {
    return (
      <Parent
        inputRef={el => this.inputElement = el}
      />
    );
  }
}

这里,ref回调首先被指定Grandparent。它被传递到Parent作为一个常规的支柱被称为inputRefParent并将它传递到CustomTextInput一个支柱。最后,CustomTextInput读取inputRefprop并将传递的函数作为ref属性附加到<input>。其结果是,this.inputElementGrandparent将被设置为对应于所述DOM节点<input>中的元素CustomTextInput。

所有考虑的事情,我们建议尽可能不暴露DOM节点,但这可以是一个有用的泄露开口。请注意,此方法要求您向子组件添加一些代码。如果您完全无法控制子组件实现,则最后一个选项是使用findDOMNode(),但不鼓励。

posted @ 2017-06-29 17:19  一纸折寒  阅读(752)  评论(0编辑  收藏  举报