在一般的 React 資料流狀況下
父組件和子組件間只能透過 props 進行溝通
但是在偶爾
非常非常偶爾
的情況下
我們還是會需要在資料流以外對子組件進行變動
像是觸發動畫、音樂媒體的回放等等
像這種時候
可以透過refs
來達成
下面就來看看要怎麼作用這個refs
吧 :
refs
將 DOM 物件作為參數直接呼叫回調函式
我們可以在渲染出來的 html 標籤直接加上refs
的屬性:
render() {
return (
<div>
<input
type="text"
ref={(input) => { this.textInput = input; }}
/>
<input
type="button"
value="Focus the text input"
onClick={this.focusTextInput}
/>
</div>
);
}
這是官方文件中的範例程式
在 input 標籤中加上一個refs
屬性
將參數 input 把 DOM 物件傳遞給組件
故當按鈕被按下的時候
組件可以透過this.textInput
找到輸入欄位這個節點
並且對其執行focus()
除了 DOM 物件節點refs
也可以對組件作用:
import React from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component {
componentDidMount() {
console.log(this.textInput);
}
render() {
return (
<InputBlock
ref={(input) => { this.textInput = input; }} />
);
}
}
class InputBlock extends React.Component{
render(){
return (
<div>
<input type="text" value=""/>
</div>
);
}
}
export default App;
當refs
的對象是一個組件的時候
參數會變為傳遞整個安裝好的組件
import React from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component {
constructor(props) {
super(props);
this.focusTextInput = this.focusTextInput.bind(this);
}
focusTextInput() {
this.textInput.focus();
}
render() {
return (
<div>
<input
type="text"
ref={(input) => { this.textInput = input; }}
/>
<input
type="button"
value="Focus the text input"
onClick={this.focusTextInput}
/>
</div>
);
}
}
class AutoFocusTextInput extends React.Component {
componentDidMount() {
this.textInput.focusTextInput();
}
render() {
return (
<App
ref={(input) => { this.textInput = input; }} />
);
}
}
export default AutoFocusTextInput;
在這段程式碼用來模擬 初始狀態為已經 focus 輸入欄位 的狀態
這個 AutoFocusTextInput 組件渲染 App 組件
並且在 AutoFocusTextInput 安裝完成的時候透過refs
執行 App 組件內部的focusTextInput()
因為在這裡refs
將 App 組件作為參數呼叫函式componentDidMount()
所以才找的到componentDidMount()
這個函式並且正常執行
refs
在 function 型態的組件中沒辦法使用,因為沒有實例(instances)。refs
使用前要先考慮是否可以使用狀態資料直接達成,避免過度使用。refs
,父組件可以將函式作為特殊的 props 傳遞進去,但一般不建議這麼做。refs
被定義做 inline function,那麼每次更新都會被執行兩次,這是因為 React 重新渲染的時候會先清除舊有的再重新產生新的,可以透過改為為 class 型組件中的綁定函式解決這個問題。
- Eva Vue.js 30天隨身包
- Ben那些年,我們一起錯過的Javascript
- Ray激戰ReactJS 30天
Day21 end
by 瑞Ray =͟͟͞͞( •̀д•́)