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.inputElement
在Parent
将被设置为对应于所述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
作为一个常规的支柱被称为inputRef
,Parent
并将它传递到CustomTextInput
一个支柱。最后,CustomTextInput
读取inputRefprop
并将传递的函数作为ref属性附加到<input>
。其结果是,this.inputElement
在Grandparent
将被设置为对应于所述DOM节点<input>
中的元素CustomTextInput。
所有考虑的事情,我们建议尽可能不暴露DOM节点,但这可以是一个有用的泄露开口。请注意,此方法要求您向子组件添加一些代码。如果您完全无法控制子组件实现,则最后一个选项是使用findDOMNode()
,但不鼓励。