React組件refs的使用詳解
ref顧名思義我們知道,其實(shí)它就可以被看座是一個(gè)組件的參考,也可以說(shuō)是一個(gè)標(biāo)識(shí)。作為組件的屬性,其屬性值可以是一個(gè)字符串也可以是一個(gè)函數(shù)。
其實(shí),ref的使用不是必須的。即使是在其適用的場(chǎng)景中也不是非用不可的,因?yàn)槭褂胷ef實(shí)現(xiàn)的功能同樣可以轉(zhuǎn)化成其他的方法來(lái)實(shí)現(xiàn)。但是,既然ref有其適用的場(chǎng)景,那也就是說(shuō)ref自有其優(yōu)勢(shì)。關(guān)于這一點(diǎn)和ref的適用場(chǎng)景,官方文檔中是這樣說(shuō)的:
在從 render 方法中返回 UI 結(jié)構(gòu)之后,你可能想沖出 React 虛擬 DOM 的限制,在 render 返回的組件實(shí)例上調(diào)用某些方法。通常來(lái)說(shuō),這樣做對(duì)于應(yīng)用中的數(shù)據(jù)流動(dòng)是不必要的,因?yàn)榛钴S的數(shù)據(jù)( Reactive data )流總是確保最新的 props 被傳遞到每一個(gè)從 render() 輸出的子級(jí)中去。然而,仍然有幾個(gè)場(chǎng)景使用這種方式是必須的,或者說(shuō)是有益的:查找渲染出的組件的DOM標(biāo)記(可以認(rèn)為是DOM的標(biāo)識(shí)ID),在一個(gè)大型的非React應(yīng)用中使用React組件或者是將你現(xiàn)有的代碼轉(zhuǎn)化成React。
下面我們來(lái)看這樣的一個(gè)場(chǎng)景(下面的例子經(jīng)常被用于ref的講解,可見(jiàn)下面描述的場(chǎng)景應(yīng)該是比較經(jīng)典的):通過(guò)某個(gè)事件使<input />元素的值被設(shè)為空字符串,然后使該<input />元素獲得焦點(diǎn)。
var App = React.createClass({
getInitialState: function() {
return {userInput: ''};
},
handleChange: function(e) {
this.setState({userInput: e.target.value});
},
clearAndFocusInput: function() {
this.setState({userInput: ''}); // 設(shè)置值為空字符串
//這里想要實(shí)現(xiàn)獲得焦點(diǎn)
},
render: function() {
return (
<div>
<input
value={this.state.userInput}
onChange={this.handleChange}
/>
<input type="button"
value="Reset And Focus"
onClick={this.clearAndFocusInput}
/>
</div>
);
}
});
在上面例子中,我們已經(jīng)實(shí)現(xiàn)了點(diǎn)擊按鈕通知input元素將值設(shè)為空字符串,但是還沒(méi)有實(shí)現(xiàn)使input元素獲得焦點(diǎn)。這實(shí)現(xiàn)起來(lái)有些困難,因?yàn)樵趓ender()中返回的并不是實(shí)際的子組件的組合,僅僅是一個(gè)特定時(shí)間特定實(shí)例的描述。這句話感覺(jué)挺繞的,其實(shí)render返回的是虛擬的DOM,并不是真實(shí)的DOM。因此我們不需要僅僅著眼于那些從render()中返回的那些組件。
那說(shuō)到這,對(duì)于我們?nèi)绾螌?shí)現(xiàn)獲得焦點(diǎn)并沒(méi)有太大的幫助。要想實(shí)現(xiàn)獲得焦點(diǎn)這個(gè)功能我們需要借助ref來(lái)實(shí)現(xiàn)。上面我們提到過(guò)ref的值有兩種類型,一種是字符串、一種是回調(diào)函數(shù)。
ref字符串上屬性
React支持一個(gè)特殊的屬性,你可以將這個(gè)屬性加在任何通過(guò)render()返回的組件中。這也就是說(shuō)對(duì)render()返回的組件進(jìn)行一個(gè)標(biāo)記,可以方便的定位的這個(gè)組件實(shí)例。這就是ref的作用。
ref的形式如下
<input ref="myInput" />
要想訪問(wèn)這個(gè)實(shí)例,可以通過(guò)this.refs來(lái)訪問(wèn):
this.refs.myInput
先前版本中,我們可以通過(guò)React.findDOMNode(this.refs.myInput)來(lái)訪問(wèn)組件的DOM。但是現(xiàn)在,已經(jīng)放棄了findDOMNode函數(shù)了,可以直接使用this.refs.myInput來(lái)進(jìn)行訪問(wèn)。
ref回調(diào)函數(shù)
ref屬性也可以是一個(gè)回調(diào)函數(shù)而不是一個(gè)名字。 這個(gè)函數(shù)將要在組件被掛載之后立即執(zhí)行。這個(gè)參照的組件將會(huì)作為該函數(shù)的參數(shù),這個(gè)函數(shù)可以立即使用這個(gè)組件參數(shù),當(dāng)然也可以將其保存供以后使用。
其形式也比較簡(jiǎn)單:
render: function() {
return <TextInput ref={(c) => this._input = c} } />;
},
componentDidMount: function() {
this._input.focus();
},
或者是
render: function() {
return (
<TextInput
ref={function(input) {
if (input != null) {
input.focus();
}
}} />
);
},
這里需要注意,當(dāng)這個(gè)參照組件被卸載并且這個(gè)ref改變的時(shí)候,先前的ref的參數(shù)值將為null。這將有效的防止了內(nèi)存的泄露。所以在上面代碼中會(huì)有if判斷:
if(input != null){
input.focus();
}
上面介紹了ref的使用場(chǎng)景和方法,下面我們就將上面的例子來(lái)補(bǔ)充完整,從而實(shí)現(xiàn)獲得焦點(diǎn)的功能
var App = React.createClass({
getInitialState: function() {
return {userInput: ''};
},
handleChange: function(e) {
this.setState({userInput: e.target.value});
},
clearAndFocusInput: function() {
this.setState({userInput: ''}); // Clear the input
// We wish to focus the <input /> now!
if (this.refs.myTextInput !== null) {
this.refs.myTextInput.focus();
}
},
render: function() {
return (
<div>
<input
value={this.state.userInput}
onChange={this.handleChange}
ref=”myTextInput”
/>
<input
type="button"
value="Reset And Focus"
onClick={this.clearAndFocusInput}
/>
</div>
);
}
});
ReactDOM.render(
<App />,
document.getElementById('content')
);
在這個(gè)例子中, render 函數(shù)返回一個(gè) <input /> 實(shí)例的描述。但是真正的實(shí)例通過(guò) this.refs. myTextInput獲取。只要 render 返回的某個(gè)子組件帶有 ref="myTextInput" ,this.refs. myTextInput就會(huì)獲取到正確的實(shí)例。
上面就是ref的所有內(nèi)容,更多關(guān)于ref的介紹可以參考Ref to Components。
對(duì)于ref我們就介紹到這,希望本文對(duì)大家有所幫助。也希望大家多多支持腳本之家。
相關(guān)文章
使用react-dnd編寫(xiě)一個(gè)可拖拽排列的list
這篇文章主要為大家詳細(xì)介紹了如何使用react-dnd編寫(xiě)一個(gè)可拖拽排列的list,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03
ReactNative短信驗(yàn)證碼倒計(jì)時(shí)控件的實(shí)現(xiàn)代碼
本篇文章主要介紹了ReactNative短信驗(yàn)證碼倒計(jì)時(shí)控件的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
react路由v6版本NavLink的兩個(gè)小坑及解決
這篇文章主要介紹了react路由v6版本NavLink的兩個(gè)小坑及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10
React封裝自定義Hook捕獲所有錯(cuò)誤的實(shí)現(xiàn)方法
在 React 開(kāi)發(fā)中,錯(cuò)誤處理是確保應(yīng)用穩(wěn)定性和用戶體驗(yàn)的重要部分,React 提供了多種錯(cuò)誤捕獲方式,包括錯(cuò)誤邊界**等,本文將詳細(xì)介紹這些方法,并展示如何封裝一個(gè)能夠捕獲所有同步和異步錯(cuò)誤的自定義 Hook,需要的朋友可以參考下2024-12-12
詳解react內(nèi)聯(lián)樣式使用webpack將px轉(zhuǎn)rem
這篇文章主要介紹了詳解react內(nèi)聯(lián)樣式使用webpack將px轉(zhuǎn)rem,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09
淺談React組件props默認(rèn)值的設(shè)置
本文主要介紹了淺談React組件props默認(rèn)值的設(shè)置,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
簡(jiǎn)單的React SSR服務(wù)器渲染實(shí)現(xiàn)
這篇文章主要介紹了簡(jiǎn)單的React SSR服務(wù)器渲染實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12
詳解React開(kāi)發(fā)中使用require.ensure()按需加載ES6組件
本篇文章主要介紹了詳解React開(kāi)發(fā)中使用require.ensure()按需加載ES6組件,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-05-05
在react項(xiàng)目中webpack使用mock數(shù)據(jù)的操作方法
這篇文章主要介紹了在react項(xiàng)目中webpack使用mock數(shù)據(jù)的操作方法,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-06-06

