Yerleşik Bileşenler
PreffX, her bileşenin ikinci argümanı (utils) aracılığıyla erişilebilen dört yerleşik bileşenle birlikte gelir. Bu bileşenler, ek bağımlılıklara ihtiyaç duymadan yaygın kullanıcı arayüzü (UI) kalıplarını çözümler.
| Bileşen | Amaç | Müsaitlik |
|---|---|---|
For | Reaktif öğeler içeren listeleri render edin | utils.For |
Catch | Render hatalarını yakalayın ve yönetin | utils.Catch |
Portal | Alt öğeleri farklı bir DOM düğümüne işle | utils.Portal |
Defer | Bir değer hazır olana kadar yer tutucu göster | utils.Defer |
Suspense | Callback içindeki tüm kaynaklar alınana kadar yedek (fallback) içeriği gösterir | utils.Suspense |
For
Reaktif liste oluşturucu. Öğe sinyali (veya düz bir dizi) kabul eder ve yalnızca değişen öğeleri yeniden oluşturur. Liste boş olduğunda gösterilecek isteğe bağlı bir fallback (yedek görünüm) desteği sunar.
Tür İmzası
const For: PC<{
items: Signal<any[]>;
callback: (item: any) => any;
fallback?: any;
}>Parametreler
| Parametre | Tür | Zorunlu | Açıklama |
|---|---|---|---|
items | Signal<any[]> | Evet | Öğe dizisini tutan bir sinyal. Sinyal değiştiğinde For, listeyi verimli bir şekilde günceller; eklenen öğeler ekrana çizilir, kaldırılan öğeler ise temizlenir. |
callback | (item: any) => any | Evet | Her bir öğe için çağrılan fonksiyon. O öğe için oluşturulacak JSX'i döndürür. Döndürülen değer önbelleğe alınır ve yalnızca öğenin kendi değeri değiştiğinde yeniden hesaplanır. |
fallback | any | Hayır | Dizi boş olduğunda oluşturulan içerik. |
Kullanım
import type { PC } from 'preffx';
type Item = { id: number; name: string };
const App: PC = (_, { signal, For }) => {
const items = signal<Item[]>([
{ id: 1, name: 'Alpha' },
{ id: 2, name: 'Beta' },
{ id: 3, name: 'Gamma' },
]);
return (
<ul>
<For
items={items}
callback={(item: Item) => (
<li key={item.id}>{item.name}</li>
)}
fallback={<li>No items</li>}
/>
</ul>
);
};Reaktif güncellemeler
Signal içindeki diziyi değiştirdiğinizde, DOM otomatik olarak güncellenir:
// Add an item
items.value = [...items.value, { id: 4, name: 'Delta' }];
// Remove an item
items.value = items.value.filter((i) => i.id !== 2);
// Replace all items
items.value = [];
// -> fallback "No items" is shownDizi içindeki sinyal öğeleri
Dizideki her bir öğe başlı başına bir sinyal olabilir. Bir öğenin sinyal değeri değiştiğinde, yalnızca o öğenin çıktısı yeniden hesaplanır:
const items = signal([
signal({ id: 1, name: 'Alpha' }),
signal({ id: 2, name: 'Beta' }),
]);
// Update the second item — only "Beta" re-renders
items.value[1].value = { id: 2, name: 'BETA' };Catch
Alt bileşenler tarafından fırlatılan (veya döndürülen) hataları yakalar ve bunların yerine bir yedek (fallback) bileşen render eder. React Error Boundaries'den esinlenilmiştir.
Tür İmzası
const Catch: PC<{
fallback?: any;
children?: any | any[];
}>Parametreler
| Parametre | Tür | Zorunlu | Açıklama |
|---|---|---|---|
children | any | any[] | Hayır | Oluşturulacak (render edilecek) alt öğeler. Herhangi bir alt öğe bir Error örneği ise (veya böyle bir örnek döndürüyorsa), hata yakalanır. |
fallback | any | Hayır | Hatalar yakalandığında gösterilecek içerik. Statik bir değer veya { errors, ...extraProps } parametresini alan bir fonksiyon bileşeni olabilir. |
Statik içerik olarak Fallback
import type { PC } from 'preffx';
const App: PC = (_, { Catch }) => {
return (
<div>
<Catch fallback={<div>Something went wrong</div>}>
<MaybeBrokenComponent />
</Catch>
</div>
);
};Fonksiyonel bileşen olarak yedek (fallback)
Fallback fonksiyonu, errors (yakalanan hatalardan oluşan dizi) ve <Catch> bileşenine aktarılan diğer tüm prop'ları alır:
const App: PC = (_, { Catch }) => {
return (
<Catch
fallback={({ errors }) => (
<div class="error-fallback">
<h3>{errors.length} error(s) occurred</h3>
</div>
)}
>
<UnstableComponent />
</Catch>
);
};Yedek bileşene (fallback) fazladan prop'lar aktarma
const App: PC = (_, { Catch }) => {
return (
<Catch
fallback={({ errors, severity }) => (
<div class={severity}>
Errors: {errors.length}
</div>
)}
severity="critical"
>
<UnstableComponent />
</Catch>
);
};Hatalar nasıl tespit edilir
Catch, tüm alt öğeleri özyinelemeli olarak ( flat(Infinity) kullanarak) tarar. Error örneği olan ( instanceof Error aracılığıyla) herhangi bir alt öğe, yedek (fallback) mekanizmasını tetikler.
Portal
Alt öğeleri, bileşenin kökünün dışındaki farklı bir DOM düğümüne işler. Modal pencereler, araç ipuçları, açılır menüler ve bildirimler için kullanışlıdır.
Tür İmzası
const Portal: PC<{
root: HTMLElement;
children?: any | any[];
}>Parametreler
| Parametre | Tür | Zorunlu | Açıklama |
|---|---|---|---|
root | HTMLElement | Evet | Alt öğelerin oluşturulacağı hedef DOM öğesi. |
children | any | any[] | Hayır | Portal kökünün içinde oluşturulacak içerik. |
Temel Kullanım
import type { PC } from 'preffx';
const Modal: PC = (_, { Portal }) => {
const portalRoot = document.getElementById('modal-root')!;
return (
<Portal root={portalRoot}>
<div class="modal-overlay">
<div class="modal-content">Hello from portal!</div>
</div>
</Portal>
);
};Portal içindeki reaktif içerik
Portal içindeki çocuklar tamamen reaktiftir; sinyaller onları otomatik olarak günceller:
const Notification: PC<{ message: string }> = (
{ message },
{ signal, Portal },
) => {
const count = signal(0);
return (
<div>
<Portal root={document.getElementById('toast-root')!}>
<span id="notification-count">{count}</span>
</Portal>
<button onClick={() => (count.value += 1)}>+</button>
</div>
);
};Temizleme
Üst bileşen yok edildiğinde, Portal otomatik olarak alt bileşenlerini temizler ve root.replaceChildren() aracılığıyla portal kökünü temizler.
Kökü olmadan
Eğer root null veya undefined ise, Portal hiçbir şey render etmez:
<Portal root={null} children={<span>Won't appear</span>} />
// renders nothingDefer
Gerçek değer hazırlanırken (örneğin, bir Promise'in sonuçlanması veya Promise olmayan bir değerin alınmasına dair bir sinyal beklenirken) bir başlangıç yer tutucu değeri gösterir.
Tür İmzası
const Defer: PC<{
initial?: any;
value: Signal<any>;
}>Parametreler
| Parametre | Tür | Zorunlu | Açıklama |
|---|---|---|---|
initial | any | Hayır | value bir Promise içerdiğinde veya henüz hazır olmadığında görüntülenen yer tutucu içerik. |
value | Signal<any> | Evet | Değeri gözlemlenen bir sinyal. Sinyalin çözümlenen değeri bir Promise olmadığında, initial içeriğinin yerini alır. |
Bir Promise'i ertele
import type { PC } from 'preffx';
const SlowData: PC = (_, { signal, Defer }) => {
const data = signal(
new Promise<string>((resolve) =>
setTimeout(() => resolve('Loaded!'), 2000)
)
);
return (
<Defer
initial={<div>Loading...</div>}
value={data}
/>
);
};Oluşturma (rendering) sırası:
- Hemen
Loading...gösterir. - 2 saniye sonra, Promise çözümlendiğinde
Loaded!gösterir.
Düz (Promise olmayan) bir değeri erteleme
Eğer sinyal halihazırda düz bir değer (Promise olmayan) tutuyorsa, Defer bunu hemen oluşturur; initial (başlangıç değeri) atlanır:
<Defer
initial="Waiting..."
value={signal('Real content')}
/>
// Immediately renders "Real content"Promise'ten düz bir değere reaktif geçiş
Bir sinyal Promise'ten düz bir değere dönüştüğünde, Defer yer tutucudan gerçek içeriğe geçer:
const DynamicDefer: PC = (_, { signal, effect, Defer, onMount }) => {
const value = signal(new Promise(() => {})); // pending promise
onMount(() => {
setTimeout(() => {
value.value = 'Finally resolved!';
}, 1000);
});
return <Defer initial="Loading..." value={value} />;
};Defer ile dizi çocukları
Defer, JSX düğümlerinden oluşan diziler de dahil olmak üzere her türlü içerikle çalışır:
const items = signal([
<span id="a">Alpha</span>,
<span id="b">Beta</span>,
]);
return (
<Defer
initial={[<div>Loading...</div>]}
value={items}
/>
);
// Renders <span>Alpha</span><span>Beta</span> immediatelyTemizleme
Üst bileşen yok edildiğinde, Defer dahili sinyal takibini otomatik olarak temizler.
Suspense
Suspense, callback'i içinde oluşturulan kaynakları gruplayan bir sınırdır. Bunlardan herhangi biri bekleme (pending) durumundayken fallback görüntülenir; hepsi tamamlandığında ise asıl içerik ekrana gelir.
Tür İmzası
const Suspense: PC<{
callback: () => any;
fallback?: any;
}>Parametreler
| Parametre | Tür | Zorunlu | Açıklama |
|---|---|---|---|
callback | () => any | Evet | İçerik ağacını gecikmeli (lazy) olarak oluşturur; içinde oluşturulan kaynaklar takip edilir. |
fallback | any | Hayır | Sınır (boundary) içindeki herhangi bir kaynak bekleme durumundayken görüntülenir. |
Temel Kullanım
import type { PC } from 'preffx';
const Profile: PC = (_, { resource }) => {
const [user] = resource(async () => (await fetch('/api/user')).json());
return <h1>{user.state.value?.name ?? '...'}</h1>;
};
export const ProfilePage: PC = (_, { Suspense }) => {
return (
<Suspense callback={() => <Profile />} fallback={<p>Loading...</p>} />
);
};SSR
Sunucuda, sınır (boundary) kaynaklarını preload() için kaydeder ve çözümlenen veriyi gömer; istemcide ise veriyi yeniden getirmeden "hydrate" eder.