Refs and the DOM
典型的React数据流中,父组件通过props
与子组件通信。但有时父组件需要在这个数据流之外与子组件通信,可能是修改子组件实例或者DOM。refs
属性提供了这样的途径。比如以下场景:
- 管理焦点,文本选择,媒体播放
- 触发动画
- 集成第三方DOM库
Ref回调属性
ref
属性可以附加在任何组件上,接受一个函数作为其值,该函数在组件mounted
或unmounted
后立即执行,参数为该组件实例的引用。当ref
属性附在DOM元素上,回调函数参数为该DOM元素的引用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| class CustomTextInput extends React.Component { constructor(props) { super(props); this.focus = this.focus.bind(this); } focus() { this.textInput.focus(); } render() { return ( <div> <input type="text" ref={(input) => { this.textInput = input; }} /> <input type="button" value="Focus the text input" onClick={this.focus} /> </div> ); } }
|
组件mounted
时,回调函数参数为DOM的引用;组件unmounted
时,回调函数参数为null
。
老的API中,ref
属性值为字符串,并通过this.refs.*
进行引用,但这样有些问题,未来会移除这个功能,建议使用回调函数。
ref
属性不能用于函数式组件,因为函数式组件不存在实例,只能在函数式组件内部使用,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| function CustomTextInput(props) { 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> ); }
|
警告
回调函数为内联函数时,组件update
时会执行两次,第一次引用为null
,第二次为该实例的引用。