Preactへの移行 (Reactから)
preact/compat
は、Reactエコシステムの多くのライブラリを活用し、Preactでそれらを使用できるようにする互換性レイヤーです。既存のReactアプリケーションをお持ちの場合は、Preactを試すための推奨方法です。
これにより、ワークフローやコードベースを変更せずに、React/ReactDOMコードを書き続けることができます。preact/compat
はバンドルサイズに約2kbを追加しますが、npmで見つかる可能性のある既存のReactモジュールのほとんどをサポートするという利点があります。preact/compat
パッケージは、Preactのコアの上に必要な調整をすべて提供し、単一のモジュールでreact
とreact-dom
のように動作するようにします。
compatの設定
preact/compat
を設定するには、react
とreact-dom
をpreact/compat
にエイリアスする必要があります。はじめにのページでは、さまざまなバンドラでのエイリアスの設定方法について詳しく説明しています。
PureComponent
PureComponent
クラスはComponent
と同様に機能します。違いは、新しいpropsが古いpropsと等しい場合、PureComponent
はレンダリングをスキップすることです。これを行うには、参照の等価性を確認することで、古いpropsと新しいpropsを浅い比較で比較します。これにより、不要な再レンダリングを回避することで、アプリケーションの速度を大幅に向上させることができます。これは、デフォルトの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
の利点は、レンダリングにコストがかかる場合にのみ有効であることに注意してください。単純な子ツリーの場合、propsの比較のオーバーヘッドと比較して、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;
})
比較関数は、2つのpropsオブジェクトが**等しい**かどうかを確認するのに対し、
shouldComponentUpdate
はそれらが異なるかどうかを確認するという点で、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 (実験的)
Suspense
の主な考え方は、ツリーの下位にあるコンポーネントがまだ読み込み中である間に、UIの一部に何らかのプレースホルダーコンテンツを表示できるようにすることです。これの一般的なユースケースは、レンダリングする前にネットワークからコンポーネントを読み込む必要があるコード分割です。
import { Suspense, lazy } from 'preact/compat';
const SomeComponent = lazy(() => import('./SomeComponent'));
// Usage
<Suspense fallback={<div>loading...</div>}>
<Foo>
<SomeComponent />
</Foo>
</Suspense>
この例では、SomeComponent
が読み込まれ、Promiseが解決されるまで、UIに読み込み中...
テキストが表示されます。
この機能は実験的なものであり、バグが含まれている可能性があります。テストの可視性を高めるために、早期プレビューとして含めました。本番環境での使用はお勧めしません。