四、特殊的ref
ref不仅可以用来获取表单元素,还可以用来获取其他任意DOM元素,甚至可以用来获取React组价实例。可以通过ref控制元素的焦点、文本的选择或者和第三方操作DOM的库集成。
ref破坏了React中以props为数据传递介质的典型数据流。
1,在DOM元素上使用ref
当组件被挂载时,回调函数会接收当前DOM元素作为参数,在组件被卸载时,回调函数会接收null作为参数。
class User extends Component { constructor(props) { super(props); } componentDidMount(){ // 通过ref让input自动获取焦点 this.textInput.focus(); } render() { return ( <div> <input type="text" ref={(input) => {this.textInput = input}} /> </div> ) } } export default User;
2,在组件上使用ref
此时ref接收的参数是当前组件的实例,这提供了一种在组件外部操作组件的方式。
//父组件 class Container extends Component { constructor(props) { super(props); this.handleClick = this.handleClick.bind(this); } handleClick(){ // 通过ref调用User组件的方法 this.inputInstance.blur(); } render() { return ( <div> <User ref={(input) => {this.inputInstance = input}} /> </div> ) } } export default Container; //子组件 class User extends Component { constructor(props) { super(props); this.blur = this.blur.bind(this); } componentDidMount(){ // 通过ref让input自动获取焦点 this.textInput.focus(); } // 让input失去焦点 blur() { this.textInput.blur(); } render() { return ( <div> <input type="text" ref={(input) => {this.textInput = input}} /> </div> ) } } export default User;
只能为类组件定义ref属性,不能为函数组件定义ref属性。
3,父组件访问子组件的DOM节点
在子组件的DOM上定义ref,ref是父组件传递给子组件的一个回调函数,回调函数可以通过一个自定义的属性传递,例如inputRef,这样父组件的回调函数就能获取到这个DOM元素。
function Children(props) { return ( <div> <input ref={props.inputRef} /> </div> ) } class Container extends Component { constructor(props) { super(props); } render() { // 自定义一个属性inputRef,值是一个函数 return ( <div> <Children inputRef={el => this.inputElement = el} /> </div> ) } } export default Container;