iT邦幫忙

2021 iThome 鐵人賽

DAY 24
0
Modern Web

前端日常,每天 React 一下系列 第 24

【Day 23】與 DOM 的互動:Ref

  • 分享至 

  • xImage
  •  

Ref

Ref 擁有以下特色:

  • 不須重新渲染就可以更新值
  • 直接抓取 DOM 來控制 DOM 的行為
  • 可以在 render 方法內建立 React element

通常來說,只在不牽涉畫面顯示,
如管理 focus、選擇文字或影音播放時
才會使用到 Ref。

Ref 屬於命令式(Imperative)編程,官方建議不要在可以宣告性(Declarative)完成事情的地方使用 Ref。


建立 Ref

呼叫 createRef 可以建立新的 Ref

const ref = React.createRef();
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    return <div ref={this.myRef} />;
  }
}

Ref 藉由 ref 參數依附在 React element 上
當 component 建立後,
將 Ref 賦值到某個 instance 的屬性上,
之後便能在整個 component 內被參考到。


存取 Ref

const node = this.myRef.current;

藉由 current 屬性
可以取得指向該 DOM 節點的參考


Ref 的值

Ref 的值會根據節點的類型而有所不同:

  • 在 HTML element 上使用 ref 參數時,使用 React.createRef() 建立 ref 會取得它底下的 DOM element 來做為它的 current 屬性。
  • 在客製化的 class component 使用 ref 參數時,ref 取得被 mount 的 component 上的 instance 來當作他的 current

function component 沒有 instance,因此無法使用 ref

寫法一

myRef = React.creatRef();

console.log(this.myRef);
console.log(this.myRef.current);
console.log(this.myRef.current.innerHTML);
render(){
	return <div ref ={this.myRef}>內容</div>
}

寫法二

myRef = null;

console.log(this.myRef);
console.log(this.myRef);
console.log(this.myRef.innerHTML);
render(){
	return <div ref ={node => this.myRef = node }>內容</div>
}

其他使用方式

DOM Element 的用法

class CustomTextInput extends React.Component {
  constructor(props) {
    super(props);
    // 產生一個可以儲存 textInput DOM element 的 ref
    this.textInput = React.createRef();
    this.focusTextInput = this.focusTextInput.bind(this);
  }

  focusTextInput() {
    // 特別利用原生的 DOM API 來關注文字的輸入
    // 注意:我們正利用「current」來取得 DOM 節點
    this.textInput.current.focus();
  }

  render() {
    // 告訴 React 我們想要將 <input> ref
    // 和我們在 constructor 產生的 `textInput` 連結
    return (
      <div>
        <input
          type="text"
          ref={this.textInput} />
        <input
          type="button"
          value="Focus the text input"
          onClick={this.focusTextInput}
        />
      </div>
    );
  }
}

React 會在 component mount 的時候
將 DOM element 賦值到 current 屬性,
並在 unmount 時將它清空回 null。

Ref 的更新發生在生命週期
componentDidMount 或
componentDidUpdate 之前。


Class Component 的用法

class AutoFocusTextInput extends React.Component {
  constructor(props) {
    super(props);
    this.textInput = React.createRef();
  }

  componentDidMount() {
    this.textInput.current.focusTextInput();
  }

  render() {
    return (
      <CustomTextInput ref={this.textInput} />
    );
  }
}

class CustomTextInput extends React.Component {
  // ...
}

參考資料


上一篇
【Day 22】Hook 05:useReducer
下一篇
【Day 24】Hook 06:useRef
系列文
前端日常,每天 React 一下30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言