在典型的React數據流中,props是父組件與其子組件交互的惟一方式。 要修改子組件,須要使用一個新的props進行從新渲染。 javascript
可是,在某些狀況下,您須要在典型數據流以外強制修改子組件。 要修改的子組件能夠是React組件實例,也能夠是DOM元素。 對於這兩種狀況,React提供了一個如下這樣的功能。java
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> ); }
你的第一個傾向多是使用refs
在你的應用中「make things happen」
。 component
若是是這種狀況,你必須花一點時間,關鍵去考慮在組件層次結構中應該擁有什麼狀態。
一般,在層次結構中處於更高級別的組件「擁有」狀態是一個讓一切便清除的最適當位置。 有關示例,請參閱本系列的第10篇《提高state》。ip