React-“Refs and the DOM”
学习是一件反反复复的事情,今天回顾react官方文档中
Refs and the DOM
,大致翻译一遍,将笔记摘录备忘。
React的典型数据流中,props是父组件和子组件交互的唯一方式。要修改子组件,你需要使用新的porps重新render它。然而有的时候我们又需要在典型数据流之外去修改一个子组件。被修改的子组件可能是一个React组件实例或者是一个DOM元素,不论哪种情况,React都为我们提供了一种解决方法。
The ref Callback Attribute
React中有一种特殊的属性(–ref),你可以将他运用到任何的组件中。ref
属性接收一个回调函数,该函数会在组件mount或者unmount之后立即被调用。
当ref属性被用在一个HTML元素上时,该ref属性的回调函数会接收其下DOM元素作为该函数的参数。例如,下面的代码使用ref回调函数来存储一个DOM节点的引用:
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
this.focus = this.focus.bind(this);
}
focus() {
//使用原生DOM API明确地使文字输入框获取焦点
this.textInput.focus();
}
render() {
//使用`ref`回掉函数将text input DOM元素的引用
//存放在this.textInput中
return (
<div>
<input
type="text"
ref={(input) => { this.textInput = input; }} />
<input
type="button"
value="Focus the text input"
onClick={this.focus}
/>
</div>
);
}
}
React会在组件加载的时候将DOM元素作为参数来调用ref回调函数,在组件卸载的时候将null作为参数调用ref回调函数。
使用ref回调函数在类中设置属性是获取DOM元素的常见模式。如果你通常使用this.refs.myRefName
来获取对元素引用,我们更推荐你使用上面的方法来代替。
当ref属性应用在自定义组件中时,ref回调函数接收已加载组件的实例作为它的参数。例如,如果我们希望将上面的CustomTextInput
包装起来并模拟在它加载后立即被点击的效果:
class AutoFocusTextInput extends React.Component {
componentDidMount() {
this.textInput.focus();
}
render() {
return (
<CustomTextInput
ref={(input) => { this.textInput = input; }} />
);
}
}
你不能在函数组件(functional components)中使用ref属性,因为它们没有实例。然而你可以在函数组件的render方法中使用ref属性:
function CustomTextInput(props) {
//textInput需要在此声明
//来确保ref回调函数可以引用它
let textInput = null;
function handleClick() {
textInput.focus();
}
return (
<div>
<input
type="text"
ref={(input) => { textInput = input; }} />
<input
type="button"
value="Focus the text input"
onClick={handleClick}
/>
</div>
);
}
不要过度使用Refs
在你的应用中使用refs的最初考虑可能只是让它正常跑起来(“make things happen”)。如果是这种情况,花点时间批判性地思考一下在组件层次结构中哪里拥有state更加合适。通常,你会发现组件层次中的更高层是拥有该state的合适位置。文章Lifting State Up讲述了一个相关例子。
欢迎关注我的小站wyuhao.com