React从入门到精通系列之(14)refs和DOM元素

十4、refs和DOM元素

在典型的React数据流中,props是父组件与其子组件交互的惟一方式。 要修改子组件,须要使用一个新的props进行从新渲染。 javascript

可是,在某些状况下,您须要在典型数据流以外强制修改子组件。 要修改的子组件能够是React组件实例,也能够是DOM元素。 对于这两种状况,React提供了一个如下这样的功能。java

经过ref属性设置回调函数

React提供能够附加到任何组件的特殊属性。 ref属性接受一个回调函数,回调函数将在组件被挂载或卸载后当即执行。react

当在HTML元素上使用ref属性时,ref回调函数接收一个基础的DOM元素做为其参数。 例如,此代码使用ref回调函数来存储对DOM节点的引用:app

import React from 'react';
import ReactDOM from 'react-dom';

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

    focus() {
        // textInput是一个标准的DOM元素
        this.textInput.focus();
    }

    render() {
        return (
            <div>
                <input type="text" ref={input => {
                    this.textInput = input;
                }}/>
                <input type="button" value="选中上面的text input" onClick={this.focus}/>
            </div>
        );
    }
}
ReactDOM.render(
    <CustomTextInput/>,
    document.getElementById('root')
);

当组件装载(mounting)时,React将使用DOM元素调用ref回调函数,并在卸载时用null调用它。dom

使用ref回调函数是为类设置一个属性来访问DOM元素的常见模式。 若是您目前正在使用this.refs.myRefName来访问DOM引用的话,我会建议你使用此模式。函数

当在自定义组件上使用ref属性时,ref回调接收组件的已装入的组件实例做为其参数。 例如,若是咱们想要包装上面的CustomTextInput来模拟它在装载(mounting)后当即被点击:this

class AutoFocusTextInput extends React.Component {
    componentDidMount() {
        this.textInput.focus();
    }
    render() {
        return (
            <CustomTextInput ref={input => {this.textInput = input; }} />
        );
    }
}

您不能在功能性组件上使用ref属性,由于它们没有实例。 可是,您可使用功能性组件的render函数内的ref属性:code

function CustomTextInput(props) {
    // 这里必须提早顶一个textInput,只有这样才能够正常执行ref回调函数
    let textInput = null;
    function click() {
        textInput.focus();
    }
    return (
        <div>
            <input type="text" ref={input => { textInput = input; }} />
            <input type="button" value="选中这个输入框" onClick={click} />
        </div>
    );
}

不要过分使用ref

你的第一个倾向多是使用refs在你的应用中“make things happen”component

若是是这种状况,你必须花一点时间,关键去考虑在组件层次结构中应该拥有什么状态。
一般,在层次结构中处于更高级别的组件“拥有”状态是一个让一切便清除的最适当位置。 有关示例,请参阅本系列的第10篇《提高state》。ip

相关文章