說明
支持我們

從 React 切換至 Preact

preact/compat 是我們的相容性層,讓你可以利用 React 生態系統中的許多函式庫,並將它們與 Preact 一起使用。如果你有現有的 React 應用程式,這是嘗試 Preact 的建議方式。

這讓你可以在不變更工作流程或程式碼庫的情況下,繼續撰寫 React/ReactDOM 程式碼。preact/compat 會為你的套件大小增加約 2kb,但優點是可以支援你在 npm 上找到的大多數現有 React 模組。preact/compat 套件在 Preact 核心之上提供了所有必要的調整,讓它可以在單一模組中像 reactreact-dom 一樣運作。



設定 compat

要設定 preact/compat,你需要將 reactreact-dom 別名設定為 preact/compat入門 頁面詳細說明了如何在各種套件管理員中設定別名。

PureComponent

PureComponent 類別的運作方式類似於 Component。不同之處在於當新道具等於舊道具時,PureComponent 會略過重新整理。為此,我們透過淺層比較舊道具和新道具,其中我們檢查每個道具屬性的參考相等性。這可以透過避免不必要的重新整理來大幅加快應用程式速度。它的運作方式是新增一個預設的 shouldComponentUpdate 生命週期掛勾。

import { render } from 'preact';
import { PureComponent } from 'preact/compat';

class Foo extends PureComponent {
  render(props) {
    console.log("render")
    return <div />
  }
}

const dom = document.getElementById('root');
render(<Foo value="3" />, dom);
// Logs: "render"

// Render a second time, doesn't log anything
render(<Foo value="3" />, dom);

請注意,PureComponent 的優點只有在重新整理很花時間時才會顯現。對於簡單的子樹,與比較道具的開銷相比,執行 render 可能會更快。

memo

memo 等於函式元件,就像 PureComponent 等於類別一樣。它在後端使用相同的比較函式,但允許你指定自己的專門函式,針對你的使用案例進行最佳化。

import { memo } from 'preact/compat';

function MyComponent(props) {
  return <div>Hello {props.name}</div>
}

// Usage with default comparison function
const Memoed = memo(MyComponent);

// Usage with custom comparison function
const Memoed2 = memo(MyComponent, (prevProps, nextProps) => {
  // Only re-render when `name' changes
  return prevProps.name === nextProps.name;
})

比較函式與 shouldComponentUpdate 不同之處在於,它檢查兩個 props 物件是否相等,而 shouldComponentUpdate 則檢查它們是否不同。

forwardRef

在撰寫元件時,有時您希望允許使用者取得樹狀結構中特定參考。使用 forwardRef,您可以「轉送」ref 屬性

import { createRef, render } from 'preact';
import { forwardRef } from 'preact/compat';

const MyComponent = forwardRef((props, ref) => {
  return <div ref={ref}>Hello world</div>;
})

// Usage: `ref` will hold the reference to the inner `div` instead of
// `MyComponent`
const ref = createRef();
render(<MyComponent ref={ref} />, dom)

此元件最適合函式庫作者使用。

入口

在少數情況下,您可能希望繼續呈現在不同的 DOM 節點中。目標 DOM 節點必須在嘗試呈現在其中之前存在。

<html>
  <body>
    <!-- App is rendered here -->
    <div id="app"></div>
    <!-- Modals should be rendered here -->
    <div id="modals"></div>
  </body>
</html>
import { createPortal } from 'preact/compat';
import MyModal from './MyModal';

function App() {
  const container = document.getElementById('modals');
  return (
    <div>
      I'm app
      {createPortal(<MyModal />, container)}
    </div>
  )
}

請記住,由於 Preact 重複使用瀏覽器的事件系統,因此事件不會透過入口容器傳遞到其他樹狀結構。

暫停(實驗性質)

Suspense 背後的主要概念是允許 UI 的區段顯示某種暫存器內容,而樹狀結構中較後面的元件仍在載入中。這項功能的常見使用案例是程式碼分割,在這種情況下,您需要從網路載入元件才能呈現在其中。

import { Suspense, lazy } from 'preact/compat';

const SomeComponent = lazy(() => import('./SomeComponent'));

// Usage
<Suspense fallback={<div>loading...</div>}>
  <Foo>
    <SomeComponent />
  </Foo>
</Suspense>

在此範例中,UI 會顯示 loading... 文字,直到載入 SomeComponent 且 Promise 已解決。

此功能為實驗性質,可能包含錯誤。我們已將其納入作為早期預覽,以增加測試能見度。我們不建議在正式環境中使用它。