參考
總會有一些情況,您需要直接參考 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 中執行完成!現在元件會在安裝時持續顯示寬度和高度。