說明
支持我們

參考

總會有一些情況,您需要直接參考 Preact 渲染的 DOM 元素或元件。參考允許您執行此操作。

一個典型的使用案例是測量 DOM 節點的實際大小。雖然可以透過 ref 取得元件實例的參考,但我們通常不建議這麼做。這會在父項和子項之間建立硬耦合,而這會破壞元件模型的可組合性。在多數情況下,直接呼叫類別元件的方法,不如傳遞回呼作為 prop 來得自然。



createRef

createRef 函式將傳回一個只有單一屬性的純物件:current。每當呼叫 render 方法時,Preact 會將 DOM 節點或元件指定給 current

class Foo extends Component {
  ref = createRef();

  componentDidMount() {
    console.log(this.ref.current);
    // Logs: [HTMLDivElement]
  }

  render() {
    return <div ref={this.ref}>foo</div>
  }
}
在 REPL 中執行

回呼參考

取得元素參考的另一種方式是傳遞函式回呼。輸入的內容會稍微多一點,但它的運作方式與 createRef 類似。

class Foo extends Component {
  ref = null;
  setRef = (dom) => this.ref = dom;

  componentDidMount() {
    console.log(this.ref);
    // Logs: [HTMLDivElement]
  }

  render() {
    return <div ref={this.setRef}>foo</div>
  }
}
在 REPL 中執行

如果 ref 回呼定義為內嵌函式,它將會被呼叫兩次。一次是傳入 null,另一次則是傳入實際參考。這是常見的錯誤,而 createRef API 透過強制使用者檢查 ref.current 是否已定義,讓這件事變得更簡單。

將所有內容組合在一起

假設我們有一個場景,需要取得 DOM 節點的參考來測量它的寬度和高度。我們有一個簡單的元件,需要用實際測量值取代 placeholder 值。

class Foo extends Component {
  // We want to use the real width from the DOM node here
  state = {
    width: 0,
    height: 0,
  };

  render(_, { width, height }) {
    return <div>Width: {width}, Height: {height}</div>;
  }
}

只有在呼叫 render 方法且元件已安裝到 DOM 中時,測量才有意義。在此之前,DOM 節點並不存在,而且嘗試測量它並沒有什麼意義。

class Foo extends Component {
  state = {
    width: 0,
    height: 0,
  };

  ref = createRef();

  componentDidMount() {
    // For safety: Check if a ref was supplied
    if (this.ref.current) {
      const dimensions = this.ref.current.getBoundingClientRect();
      this.setState({
        width: dimensions.width,
        height: dimensions.height,
      });
    }
  }

  render(_, { width, height }) {
    return (
      <div ref={this.ref}>
        Width: {width}, Height: {height}
      </div>
    );
  }
}
在 REPL 中執行

完成!現在元件會在安裝時持續顯示寬度和高度。