コンポーネント
コンポーネントは、JSXマークアップを作成するための構成要素です。各コンポーネントは、PC型(同期コンポーネント用)またはAPC型(非同期コンポーネント用)を実装する関数です。このような関数の最初の引数はパラメータ、2番目の引数は利用可能なPrefxXユーティリティです。
実装機能:
- リアクティビティ: シグナルシステム(
@preact/signals-core)を使用してリアクティブ値を生成および追跡します。再レンダリングをトリガーするのは、これらの値のみです。 - ライフサイクル管理: コンポーネントのマウント時とアンマウント時にコールバックを実行し、エフェクトを自動的に削除します。
- PrefxXユーティリティを2番目の引数として渡す: 必要なものはすべてパラメータで提供されるため、PrefxX自体からインポートする必要があるのは型のみです。
- 非同期関数のサポート: 同期関数と非同期関数の両方に対応し、プロミスが解決されるとDOMツリーを自動的に再レンダリングします。
基本的な実装
カウンターを備えたコンポーネントの最もシンプルな実装は次のようになります。
typescript
import type { PC } from 'preffx';
const MyComponent: PC = (props, { signal, computed }) => {
const { initialCount = 0 } = props;
const count = signal(initialCount);
return (
<div>
<p>Counter: {count}</p>
<button onClick={() => count.value++}>Increase</button>
</div>
);
};
const App: PC = () => {
return <MyComponent
initialCount={5}
/>;
};反応性
反応性を確保するために、@preact/signals-core をベースに実装された関数が使用されます。例えば、以下の関数です。
signal- 状態に対するリアクティブシグナルを作成します。computed- 依存値を計算します。effect- 副作用を管理します。
これらの関数は、Preact Signals ドキュメントに記載されている動作を完全に実装しています。
コンポーネントコンテキスト
各コンポーネントインスタンスに対して、親コンテキストを拡張するコンテキストが作成されます。これは、ユーティリティから取得できる通常のオブジェクトです。
tsx
import type { PC } from 'preffx';
const contextKey = 'ctx-counter';
const AnotherComponent: PC = (props, { context }) => {
// read context
const counter = context[contextKey];
return <span>
{counter}
</span>;
};
export const App: PC = (props, { signal, context }) => {
const counter = signal(0);
// modify context
context[contextKey] = counter;
return <p>
{valueFromContext}
<AnotherComponent />
</p>;
};ライフサイクル
各コンポーネントは、以下のライフサイクルユーティリティを使用できます。
onMount- コンポーネントがマウントされたとき(要素がDOMツリーに追加された後)に呼び出されます。onDestroy- コンポーネントが破棄されたとき(要素がDOMツリーから削除される前)に呼び出されます。
tsx
import type { PC } from 'preffx';
export const App: PC = (props, { onMount, onDestroy }) => {
const { count } = props;
onMount(() => {
// some mount logic
});
onDestroy(() => {
// some destroy logic
});
return <button
onClick={() => {
count.value += 1
}}
>
Count is {count}
</button>
};ID生成
idユーティリティを使用すると、コンポーネント内で使用する一意の識別子を生成できます。
tsx
import type { PC } from 'preffx';
export const App: PC = (props, { id }) => {
// get unique id
const inputId = id();
return <div>
<label>
Password:
<input
type="password"
aria-describedby={inputId}
/>
</label>
<p id={inputId}>
The password should contain at least 18 characters
</p>
</div>;
};特殊コンポーネント
ユーティリティの中でも、特に注目すべき組み込みコンポーネントは以下のとおりです。
Catch- コンポーネント内のエラー処理用、For- リアクティビティをサポートするリストのレンダリング用、Defer- 非同期で計算された値の遅延レンダリング用、Portal- PreffXルート外の要素のレンダリング用