useSyncExternalStore, harici veri depolarına (store) abone olmanızı sağlayan React Hook’udur.
- Referans
useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot?)- Kullanım
- Harici depoya abone olma
- Tarayıcı API’sine abone olma
- Mantığı özel bir hook’a çıkarma
- Sunucu taraflı render desteği ekleme
- Sorun giderme
- “The result of
getSnapshotshould be cached” hatası alıyorum subscribefonksiyonum her render’dan sonra çağırılıyor
- Store nasıl çevrilecek?
Referans
useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot?)
Harici veri deposundan değer okumak için bileşeninizin en üst kapsamında useSyncExternalStore’u çağırın.
Depodaki verinin anlık görüntüsünü döndürür. Argüman olarak iki fonksiyon geçmeniz gerekir:
subscribefonksiyonu, depoya (data store) abone olmalı (subscribe) ve abonelikten çıkmak için fonksiyon döndürmelidir.getSnapshotfonksiyonu, depodaki verinin anlık görüntüsünü okumalıdır.
Daha fazla örnek için aşağıya bakın.
Parametreler
subscribe: Bircallbackargümanı alan ve depoya abone olan fonksiyondur. Depo değiştiğinde, iletilencallbackçalıştırılır. Bu, bileşeni yeniden render eder ve (ihtiyac varsa)getSnapshoti yeniden cagirir.subscribefonksiyonu, aboneliği temizleyen bir fonksiyon döndürmelidir.getSnapshot: Bileşenin ihtiyaç duyduğu depodaki verilerin anlık görüntüsünü döndüren fonksiyondur. Veri deposu değişmemişse,getSnapshot’a yapılan çağrılar aynı değeri döndürmelidir. Depo değişirse ve döndürülen değer farklıysa (Object.isile karşılaştırıldığında), bileşen yeniden render edilir.- isteğe bağlı
getServerSnapshot: Depodaki verilerin başlangıçtaki anlık görüntüsünü döndüren fonksiyondur. Yalnızca sunucu taraflı render ya da istemcide render edilmiş çıktının hidratlanması sırasında çalıştırılır. Serileştirilerek sunucudan istemciye iletilen sunucu anlık görüntüsü, istemci ile aynı olmalıdır. Bu argümanı iletirseniz, bileşen sunucu tarafında render edilirken hata fırlatır.
Dönüş değeri
Render mantığınızda kullanabileceğiniz deponun o anki anlık görüntüsüdür.
Dikkat edilmesi gerekenler
getSnapshottarafından döndürülen depo anlık görüntüsü değiştirilemez (immutable) olmalıdır. Depoda değiştirilebilir veri varsa veriler değiştiğinde yeni bir anlık görüntü döndürün. Aksi takdirde, önbelleğe alınmış en son anlık görüntüyü döndürün.- Yeniden render esnasında farklı bir
subscribefonksiyonu geçildiğinde React, yeni geçilensubscribefonksiyonu ile depoya yeniden abone olur.subscribe’ı bileşenin dışında tanımlayarak bunu önleyebilirsiniz. - If the store is mutated during a non-blocking Transition update, React will fall back to performing that update as blocking. Specifically, for every Transition update, React will call
getSnapshota second time just before applying changes to the DOM. If it returns a different value than when it was called originally, React will restart the update from scratch, this time applying it as a blocking update, to ensure that every component on screen is reflecting the same version of the store. - It’s not recommended to suspend a render based on a store value returned by
useSyncExternalStore. The reason is that mutations to the external store cannot be marked as non-blocking Transition updates, so they will trigger the nearestSuspensefallback, replacing already-rendered content on screen with a loading spinner, which typically makes a poor UX.For example, the following are discouraged:constLazyProductDetailPage=lazy(()=>import('./ProductDetailPage.js')); functionShoppingApp(){constselectedProductId=useSyncExternalStore(...);//❌ Calling `use` with a Promise dependent on `selectedProductId` const data = use(fetchItem(selectedProductId)) // ❌ Conditionally rendering a lazy component based on `selectedProductId` return selectedProductId != null ? <LazyProductDetailPage /> : <FeaturedProducts />; }
Kullanım
Harici depoya abone olma
React bileşenlerinizin çoğu veriyi yalnızca prop, state ve context’den okur. Ancak bileşenler, bazı verileri React dışındaki bir depodan (store) okuma ihtiyacı duyabilir. Aşağıdaki durumlar buna örnektir:
- React dışında state tutan üçüncü parti state yönetim kütüphaneleri.
- Değiştirebilir değer ve değişikliklere abone olmak için olaylar (event) sunan tarayıcı API’leri.
Harici veri deposundan bir değer okumak için bileşeninizin en üst kapsamında useSyncExternalStore’u çağırın.
Veri deposundaki verilerin anlık görüntüsünü döndürür. Argüman olarak iki fonksiyon geçmeniz gerekir:
subscribefonksiyonu, depoya abone olmalı ve aboneliği sonlandıran fonksiyon döndürmelidir.getSnapshotfonksiyonu, depodan veriyi anlık görüntüsünü okumalıdır.
React, bu fonksiyonları kullanarak bileşeninizi depoya abone tutar ve değişikliklerde yeniden render eder.
Aşağıdaki örnekte todosStore, React’ın dışında veri tutan harici bir depo olacak şekilde implemente edilmiştir. TodosApp bileşeni useSyncExternalStore Hook’u ile harici depo ile bağlantı kurar.
Not
Mümkün mertebe useState ve useReducer aracılığıyla yerleşik React state’ini kullanmanızı öneririz. useSyncExternalStore API’si, bileşenlerinizi React olmayan kodlarınızla entegre etmeniz gerektiğinde kullanışlıdır.
Tarayıcı API’sine abone olma
useSyncExternalStore kullanmak için başka bir neden, tarayıcı tarafından sunulan ve zamanla değişen değerlere abone olmaktır. Örneğin, bileşeninizde ağ bağlantısının etkin olup olmadığını göstermek istiyorsunuzdur. Tarayıcı, bu bilgiyi navigator.onLine özelliği aracılığıyla sunar.
Bu değer React’ın bilgisi dışında değişebilir ve bu sebeple useSyncExternalStore ile okumanız gerekir.
getSnapshot fonksiyonunu implemente etmek için tarayıcı API’sinden geçerli değeri okuyun:
Ardından, subscribe fonksiyonunu implemente etmeniz gerekir. Örneğin, navigator.onLine değiştiğinde window nesnesi üzerinden online ve offline olayları tetiklenir. callback argümanıyla bu olaylara abone olmanız ve abonelikleri temizleyen bir fonksiyon döndürmeniz gerekir.
Artık React, harici navigator.onLine API’sinin değerini nasıl okuyacağını ve değişikliklere nasıl abone olacağını bilir. Cihazınızın ağ bağlantısı kesin ve bileşenin buna karşılık yeniden render’ı tetiklediğine dikkat edin:
Mantığı özel bir hook’a çıkarma
Usually you won’t write useSyncExternalStore directly in your components. Instead, you’ll typically call it from your own custom Hook. This lets you use the same external store from different components.
For example, this custom useOnlineStatus Hook tracks whether the network is online:
Genellikle useSyncExternalStore’u bileşenlerinizde doğrudan kullanmazsınız. Bunun yerine kendi özel Hook’unuzda çağırırsınız.
Böylece aynı harici depoyu farklı bileşenlerden de kullanabilirsiniz.
Örneğin, örnekteki özel useOnlineStatus Hook’u ağın çevrimiçi olup olmadığını takip eder:
Artık farklı bileşenler, implementasyonu sürekli tekrarlamadan useOnlineStatus çağırabilir:
Sunucu taraflı render desteği ekleme
React uygulamanız sunucu taraflı render’lama kullanıyorsa, React bileşenleriniz başlangıç HTML’ini üretmek için tarayıcı ortamının dışında da çalışacaktır. Bu durum, harici depoya bağlanırken bazı zorlukları beraberinde getirir:
- Yalnızca tarayıcıda bulunan bir API’ye bağlanıyorsanız, çalışmayacaktır çünkü sunucuda mevcut değildir.
- Üçüncü taraf bir veri deposuna bağlanıyorsanız, sunucu ve istemci arasında verilerin eşleşmesi gerekmektedir.
Bu sorunları çözmek için, useSyncExternalStore’a üçüncü argüman olarak getServerSnapshot fonksiyonunu iletin:
getServerSnapshot fonksiyonu getSnapshot’a benzer ancak yalnızca iki durumda çalışır:
- HTML oluşturulurken sunucuda çalışır.
- React’ın sunucu HTML’ini alıp etkileşimli haline getirirken yani hidratlama yaparken istemcide çalışır.
Bu durum, uygulama etkileşimli hale gelmeden önce kullanılacak olan başlangıç anlık görüntü değeri vermenizi sağlar. Sunucu taraflı render için anlamlı bir başlangıç değeriniz yoksa, istemcide render işlemini zorlamak için bu argümanı atlayın.
Not
getServerSnapshot’ın istemci tarafındaki ilk render’da sahip olduğu verilerin, sunucudan döndürdüğü verilerle birebir aynı olduğundan emin olun. Örneğin getServerSnapshot sunucuda doldurulmuş olarak gelen depo içeriği döndürdüyse, bu içeriği istemciye aktarmanız gerekir. Bunun yapmanın bir yolu, sunucu taraflı render esnasında window.MY_STORE_DATA gibi bir global tanımlayan <script> etiketi kullanmak ve ardından istemcide getServerSnapshot içinden bu global değişkeni okumaktır. Harici deponuz bunu nasıl yapacağınıza ilişkin talimatlar sağlamalıdır.
Sorun giderme
“The result of getSnapshot should be cached” hatası alıyorum
Bu hata, getSnapshot fonksiyonunuzun her çağırıldığında yeni bir nesne döndürdüğü anlamına gelir, örneğin:
getSnapshot son seferkinden farklı bir değer döndürdüğünde, React bileşeni yeniden render eder. Dolayısıyla her seferinde farklı sonuç döndürdüğünüzde sonsuz döngüye girer ve hata alırsınız.
getSnapshot nesneniz yalnızca gerçekten değiştiğinde farklı bir nesne döndürür. Deponuz değişmez (immutable) veri içeriyorsa, bu verileri doğrudan döndürebilirsiniz:
Deponuzdaki veri değişken (mutable) ise getSnapshot fonksiyonunuz değişmez anlık görüntüsünü döndürmelidir. Yani her çağrıldığında farklı nesne oluşturması gerektiği anlamına gelir. Bunun yerine, son hesaplanan anlık görüntüyü depolamalı ve depodaki veri değişmediyse bir önceki anlık görüntüyü döndürmelidir. Değişken verilerin değişip değişmediğini nasıl belirleyeceğiniz deponuza bağlıdır.
subscribe fonksiyonum her render’dan sonra çağırılıyor
Örnekteki subscribe fonksiyonu bileşenin içinde tanımlanmıştır ve bu nedenle her render’da farklıdır:
Yeniden render’lar arasında farklı bir subscribe fonksiyonu iletirseniz, React deponuza yeniden abone olur. Bu durum performans sorunlarına neden oluyorsa ve sürekli abone olmaktan kaçınmak istiyorsanız, subscribe fonksiyonunu bileşen dışına taşıyın:
Alternatif olarak, yalnızca bir takım argümanlar değiştiğinde yeniden abone olmak için subscribe fonksiyonunu useCallback Hook’una sarın:
Sam Altman, Hindistan'da The Indian Express etkinliğinde yaptığı konuşmada yapay zekânın çevresel etkilerine ilişkin tartışmalara değindi. Ülkede düzenlenen büyük bir yapay zekâ zirvesi kapsamında konuşan Altman, özellikle ChatGPT'nin yüksek miktarda su tükettiğine yönelik yaygın iddiaların gerçeği yansıtmadığını söyledi...
Nvidia, OpenAI’a devasa bir yatırım yapmaya hazırlanıyor
Altman, internette dolaşan "bir sorgu başına yaklaşık 64 litre (17 galon) su" gibi verilerin doğru olmadığını belirtti. Bu tür hesaplamaların, geçmişte veri merkezlerinde kullanılan buharlaşmalı soğutma sistemlerine dayandığını ifade eden OpenAI CEO'su, günümüzde bu teknolojinin kullanılmadığını vurguladı.
"1,5 iPhone şarjı" söylemleri doğru değil
Altman, su tüketimi iddialarını reddederken, yapay zekâ sistemlerinin artan enerji ihtiyacının ise önemli bir tartışma konusu olduğunu kabul etti. Yapay zekânın yaygınlaşmasıyla birlikte enerji talebinin arttığını belirten Altman, nükleer enerjiye geçişin hızlandırılması ve rüzgâr ile güneş gibi yenilenebilir kaynaklara daha fazla yatırım yapılması gerektiğini savundu.
1 gün önce eklendiTam Boyutta GörAltman ayrıca, bir ChatGPT sorgusunun 1,5 iPhone batarya şarjına eşdeğer enerji tükettiği yönündeki iddiaların da doğru olmadığını dile getirdi. Model eğitimi sırasında harcanan enerji ile tek bir kullanıcı sorgusunun enerji maliyetini karşılaştırmanın sağlıklı olmadığını belirten Altman, yapay zekâ sistemlerinin enerji tüketiminin eğitim süreci tamamlandıktan sonra değerlendirilmesi gerektiğini ifade etti.
© Copyright Rementis Inc. All Rights Reserved