ヘルプ
サポート

Preactへの移行 (Reactから)

preact/compatは、Reactエコシステムの多くのライブラリを活用し、Preactでそれらを使用できるようにする互換性レイヤーです。既存のReactアプリケーションをお持ちの場合は、Preactを試すための推奨方法です。

これにより、ワークフローやコードベースを変更せずに、React/ReactDOMコードを書き続けることができます。preact/compatはバンドルサイズに約2kbを追加しますが、npmで見つかる可能性のある既存のReactモジュールのほとんどをサポートするという利点があります。preact/compatパッケージは、Preactのコアの上に必要な調整をすべて提供し、単一のモジュールでreactreact-domのように動作するようにします。



compatの設定

preact/compatを設定するには、reactreact-dompreact/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に読み込み中...テキストが表示されます。

この機能は実験的なものであり、バグが含まれている可能性があります。テストの可視性を高めるために、早期プレビューとして含めました。本番環境での使用はお勧めしません。