Framework entegrasyonları · React Three Fiber
useFrame / useThree: Kare Diplomasisi ve Store Gözü
Deklaratif ağaç durağanı anlatır; canlı ürün
kare içinde mutasyon ister. Bu sayfa
useThree ile store'dan seçici okumayı ve
useFrame ile güvenli kare ticini anlatır: React render
saati ile R3F kare saati karıştırılmaz.
Holodepth bu yaprağı React hooks 101 veya Three.js
Clock / requestAnimationFrame teorisinin
tekrarı olarak yazmaz. React varsayılır
(React Vitae).
Canvas frameloop mührü
Canvas & kök sözleşme
yaprağındadır. JSX katalog haritası
Deklaratif sahne grafı
yaprağındadır. Ms bütçesi / FPS SLA
Platform · FPS mantığı
yaprağındadır. glTF yükleme bu kapının konusu değildir.
Sayfayı bitirdiğinizde şu cümleyi kurabilmelisiniz: «useThree seçici gözdür; gereksiz abonelik pahalıdır. useFrame kare ticine yazılır, her karede setState yazılmaz. Mutasyon ref/Object3D üzerindendir. priority sıra diplomasisidir. demand kökünde invalidate köprüsü gerekir. Sonraki kapı yükleme & Suspense köprüsüdür.»
Bu sayfanın sınırı · komşu konularla ayrım
Bu sayfa R3F'de kare / store diplomasisini anlatır:
- Render saati vs kare saati
useThreeseçicileri · abonelik maliyetiuseFramesözleşmesi · delta / elapsed- ref mutasyonu · priority · invalidate köprüsü
Bilinçli olarak dışarıda bırakılan konular:
- Canvas / DPR /
frameloopkök mührü → Canvas & kök sözleşme - args / attach / katalog → Deklaratif sahne grafı
- useLoader / Suspense / dispose → Yükleme & Suspense köprüsü
- Pointer / raycast → Pointer olayları & picking
- Instancing / ağır kaçış → Performans & imperatif kaçış
- FPS ms SLA → Platform FPS · React hooks temeli → React Vitae · glTF şema → format izlekleri
Kısa ayrım: Bu sayfa «karede kim neyi günceller?» · Canvas «metronom kökte nasıl mühürlenir?» · Deklaratif «ağaç nasıl yazılır?» · Platform FPS «ms bütçesi / jank».
İki saat: render ve kare
React render'ı durum değişince (veya üst yeniden çizilince) çalışır.
R3F karesi ise Canvas metronomuna bağlıdır: always ise
sürekli, demand ise geçersizkılınca. Holodepth: bu iki
saati aynı cümlede karıştırmayın. UI checkbox'ı için
setState; orbit / sallanma / trail için
useFrame.
Imperatif Three'de kendi animate döngünüzü yazarsınız.
R3F'de döngü kökte vardır; sizin işiniz o döngüye
abonelik eklemektir. Aboneliği her React render'ında yeniden
icat etmek değil, kare callback'inde Object3D'yi itmektir.
Render gerçeği anlatır; kare hareketi taşır.
useThree: seçici göz
useThree, Fiber store'undan gl,
camera, scene, size,
viewport, clock, invalidate
gibi alanları okur. Holodepth kuralı: tüm store'u değil,
ihtiyacınız olan dilimi seçin. Geniş abonelik, sık store
güncellemelerinde gereksiz React yeniden render'ı tetikleyebilir.
Seçici örnek düşüncesi: yalnız invalidate için
useThree((s) => s.invalidate); yalnız kamera için
kamera seçicisi. «Her şeyi alayım» demosu için uygundur, üretim paneli
için pahalıdır.
Store alanlarının semantiği Canvas köküne bağlıdır:
size host kutusundan gelir (kök sayfa),
frameloop politikası kökte mühürlenir. Bu sayfa alanı
nasıl seçici okuyacağınızı mühürler; kökü yeniden anlatmaz.
useFrame sözleşmesi
useFrame((state, delta) => { … }) her uygun karede
çağrılır. state store anlık görüntüsünü taşır;
delta saniye cinsinden kare aralığıdır. Holodepth üretim
dilinde: konum/rotasyon için çoğu zaman delta; periyodik dalga için
state.clock.elapsedTime (veya eşdeğeri). Three
getDelta tuzağının klasik anlatımı zaman omurgasındadır;
burada R3F'nin size delta'yı zaten verdiğini bilmek yeterlidir: aynı
karede ikinci bir delta icat etmeyin.
Callback içinde ağır iş (JSON parse, texture decode, büyük dizi map) jank üretir. Bu, Platform FPS dilim teşhisine köprüler; Holodepth burada kuralı koyar: useFrame ince olsun, ağır işi kare dışına veya worker'a itin.
Mutasyon: ref hattı
Kare içinde mesh konumunu değiştirmenin yolu Object3D referansıdır:
useRef ile mesh'e bağlanıp
ref.current.rotation.y += speed * delta. Bu, deklaratif
prop yazımını her karede yeniden başlatmaz; React ağacını
yeniden uzlaştırmaz.
Deklaratif sayfada mühürlenen «tek kaynak» kuralı burada şöyle okunur:
sürekli değişen bir değeri hem position={[x,y,z]} prop
hem useFrame ile itmek çift kapıdır. Ya deklaratif (seyrek) ya kare
(sık); ikisini aynı alan için yarıştırmayın.
setState zehri
Her karede setState (veya bağlamsız store'a yüksek frekanslı
yazmak) React render selini açar. Vitrin 60 Hz ise saniyede 60 uzlaştırma
adayıdır; mobil cihazda ürün çöker. Holodepth: UI'ye yansıtılacak değer
seyreltilir (her N kare, veya eşik aşımında), 3D hareket ref'te kalır.
Hud / etiket metnini her kare güncellemek istiyorsanız DOM'u ayrı bir düşük frekanslı kanala alın veya üç boyutlu text maliyetini bilinçli kabul edin. Bu bir React temeli dersi değil; R3F köprüsünde frekans diplomatisidir.
Kare ucuz sandığınız setState, aslında ikinci bir motor çalıştırır.
priority: sıra diplomasi
Birden fazla useFrame aynı Canvas'ta yaşar. Sıra önemliyse
(önce kamera takip, sonra trail, en sonda ölçüm) priority ile şerit
ayırın. Holodepth ürün dilinde yüksek frekanslı «fizik benzeri» itiş ile
görsel süs aynı şeritte yarışmamalıdır.
| Şerit fikri | Tipik iş | Not |
|---|---|---|
| Erken | Kamera / kontrol çıktısını oturtmak | Sonraki görseller buna yaslanır |
| Orta | Meshes, trail, hafif animasyon | İnce kalsın |
| Geç | Ölçüm, debug overlay bayrağı | Üretimi kirletmesin |
Sayısal priority değerleri sürüme göre değişebilir; sözleşmeyi «hangi iş hangi şeritte» olarak yazın, magik sayıya tapmayın.
demand ve invalidate köprüsü
Kök frameloop="demand" ise kareler kendiliğinden akmaz.
Pointer sonrası, veri geldiğinde veya prop değişince
invalidate() gerekir. Canvas sayfasında panel profili bu
mühürü koydu; burada köprüyü netleştiririz: useFrame abonesi vardır ama
metronom tik atmazsa callback uyanmaz.
Karışık profil: sürekli idle motion isteyen çocuk + demand kök =
uyumsuz sözleşme. Ya kökü always yapın ya idle motion'u
bırakın ya da kontrollü invalidate üretin. Üçünü birden varsayımlarla
birleştirmeyin.
Güvenli kare: simüle abonelik
Örnekler öğretim amaçlıdır; paket sürümünüzü doğrulayın. React hook temeli anlatılmaz. Canvas kökü önceki yapraklarda mühürlü kabul edilir.
Simüle · delta ile dönüş, elapsed ile dalga. Mutasyon ref üzerinden; her karede setState yok.
import { useRef } from 'react'
import { useFrame } from '@react-three/fiber'
const SPIN_RAD_PER_SEC = 1.2
const WAVE_AMP = 0.15
export function SpinningPart({ children }) {
const root = useRef(null)
useFrame((state, delta) => {
const obj = root.current
if (!obj) return
// FPS bağımsız dönüş (radyan/s × saniye)
obj.rotation.y += SPIN_RAD_PER_SEC * delta
// Dalga: süre tabanlı (elapsed → sin)
obj.position.y = Math.sin(state.clock.elapsedTime) * WAVE_AMP
})
return <group ref={root}>{children}</group>
}
Simüle · seçici invalidate köprüsü. Panel kökü demand iken dış event sonrası tek kare uyandırır; sürekli setState döngüsü açmaz.
import { useEffect } from 'react'
import { useThree } from '@react-three/fiber'
/**
* seed değişince demand canvas'ı bir kare uyandırır.
* Sürekli animasyon için kök frameloop="always" tercih edin.
*/
export function WakeBridge({ seed }) {
const invalidate = useThree((s) => s.invalidate)
useEffect(() => {
invalidate()
}, [seed, invalidate])
return null
}
Güvenlik: useFrame içinde kullanıcı string'ini
eval / dinamik Function ile çalıştırmayın.
Uzaktan gelen animasyon eğrisi verisini doğrulayın; unbounded delta
(sekme geri dönüşü) için hız tavanı düşünün.
Kare tuzakları
- Closure bayatlığı: useFrame'de eski prop yakalamak; güncel değer için ref veya state.clock ile taze okuma.
- Koşulsuz ağır iş: her karede alloc / filtre / sort.
- Çift metronom: hem kendi rAF'iniz hem R3F döngüsü.
- demand unutkanlığı: invalidate yok · «neden dönmüyor?».
- UI sel: her kare setState ile HUD.
- Şerit kaos: priority'siz birbirini ezen abonelikler.
Picking ve event callback'leri ayrı yapraktır; useFrame içinde her kare raycast yapmak çoğu ürün için pahalıdır. Gerekirse seyreltin veya event yoluna taşıyın.
Üç kare profili
-
01 · Kare
Sürekli vitrin
- Kök
frameloop="always"- useFrame
- İnce idle / orbit destek
- Risk
- Boşta ağır callback
-
02 · Kare
Veri paneli
- Kök
demand+ invalidate- useThree
- Seçici invalidate / size
- Risk
- always unutmak · pil yenisi
-
03 · Kare
Çok abonelikli sahne
- priority
- Kontrol → görsel → ölçüm
- Mutasyon
- ref hattı · setState seyrek
- Risk
- Şeritsiz yarış
Holodepth perspektifleri
Kareyi ince tutun
useFrame bir mikro-işletmendir; uygulama çekirdeği değildir.
Gözü daraltın
useThree'de tüm store'u abone etmek çoğu zaman tembellik maliyetidir.
Frekansı ayırın
3D hareket yüksek frekans; UI metni düşük frekans. İkisini aynı boruya bağlamayın.
Teşhis maddeleri
- Render saati ile kare saati karışmış mı?
- useThree seçici mi?
- useFrame içinde setState yağmuru var mı?
- Mutasyon ref üzerinden mi?
- delta / elapsed doğru işe mi bağlandı?
- demand kökünde invalidate var mı?
- priority şeritleri yazılı mı?
- FPS SLA veya glTF loader bu sayfaya sızmış mı?
Holodepth içgörüsü
«useFrame koydum dönmedi» çoğu zaman callback hatası değil, kök metronom veya çift kaynaklı alan sorunudur. Önce saati okuyun, sonra tici yazın.
Sonraki kapı: yükleme & Suspense köprüsü
Kare canlıyken asıl yük çoğu zaman asenkron varlıktadır. Sonraki sayfa Yükleme & Suspense köprüsü useLoader, askıya alma ve dispose diplomasisini anlatır. Picking ve imperatif kaçış sonraki yapraklardadır.