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

相關文章