外部 DOM 突變
有時需要使用第三方函式庫,這些函式庫預期能夠自由突變 DOM、在其中保留狀態,或根本沒有組件邊界。有許多很棒的 UI 工具包或可重複使用的元素以這種方式運作。
在 Preact(以及 React 中類似),使用這些類型的函式庫需要您告訴虛擬 DOM 渲染/差異演算法,它不應該嘗試還原在給定組件(或它所代表的 DOM 元素)中執行的任何外部 DOM 突變。
技巧
這可以像在你的元件上定義一個 shouldComponentUpdate()
方法一樣簡單,並讓它回傳 false
class Block extends Component {
shouldComponentUpdate() {
return false;
}
}
... 或用簡寫
class Block extends Component {
shouldComponentUpdate = () => false;
}
有了這個生命週期掛鉤,並告訴 Preact 在 VDOM 樹發生變更時不要重新渲染元件,你的元件現在有一個可以被視為靜態的根 DOM 元素參考,直到元件被卸載。與任何元件一樣,這個參考只稱為 this.base
,並且對應於從 render()
回傳的根 JSX 元素。
範例演練
以下是「關閉」元件重新渲染的範例。請注意,render()
仍會在建立和掛載元件時被呼叫,以產生其初始 DOM 結構。
class Example extends Component {
shouldComponentUpdate() {
// do not re-render via diff:
return false;
}
componentWillReceiveProps(nextProps) {
// you can do something with incoming props here if you need
}
componentDidMount() {
// now mounted, can freely modify the DOM:
let thing = document.createElement('maybe-a-custom-element');
this.base.appendChild(thing);
}
componentWillUnmount() {
// component is about to be removed from the DOM, perform any cleanup.
}
render() {
return <div class="example" />;
}
}
示範
真實世界的範例
或者,在 preact-token-input 中查看此技巧的實際應用 - 它使用元件作為 DOM 中的立足點,但隨後停用更新並讓 tags-input 從那裡接手。一個更複雜的範例是 preact-richtextarea,它使用此技巧來避免重新渲染可編輯的 <iframe>
。