Bileşenlerin iletişim kurmasının birden çok yolu vardır. Bazıları kullanıcı tabanınıza uygun olabilir. Bilmem için yararlı bulduğum bazılarının listesi.
Tepki
Ebeveyn / Çocuk doğrudan iletişimi
const Child = ({fromChildToParentCallback}) => (
<div onClick={() => fromChildToParentCallback(42)}>
Click me
</div>
);
class Parent extends React.Component {
receiveChildValue = (value) => {
console.log("Parent received value from child: " + value); // value is 42
};
render() {
return (
<Child fromChildToParentCallback={this.receiveChildValue}/>
)
}
}
Burada alt bileşen, üst tarafından değeri olan bir geri aramayı çağırır ve üst, üst öğedeki çocuklar tarafından sağlanan değeri alabilir.
Uygulamanızın bir özelliğini / sayfasını oluşturursanız, geri çağrıları / durumu ( container
veya olarak da adlandırılır smart component
) yöneten tek bir ebeveyne sahip olmak ve tüm çocukların vatansız olması daha iyidir , yalnızca ebeveynlere bir şeyler bildirir. Bu şekilde ebeveynin durumunu ihtiyaç duyan herhangi bir çocuğa kolayca "paylaşabilirsiniz".
bağlam
Reaksiyon Bağlamı, durumu bileşen hiyerarşinizin kökünde tutmaya izin verir ve bu durumu, her ara bileşene sahne aktarmak zorunda kalmadan kolayca çok derin yuvalanmış bileşenlere enjekte edebilir.
Şimdiye kadar bağlam deneysel bir özellikti, ancak React 16.3'te yeni bir API mevcut.
const AppContext = React.createContext(null)
class App extends React.Component {
render() {
return (
<AppContext.Provider value={{language: "en",userId: 42}}>
<div>
...
<SomeDeeplyNestedComponent/>
...
</div>
</AppContext.Provider>
)
}
};
const SomeDeeplyNestedComponent = () => (
<AppContext.Consumer>
{({language}) => <div>App language is currently {language}</div>}
</AppContext.Consumer>
);
Tüketici render prop / children işlev modelini kullanıyor
Daha fazla ayrıntı için bu blog yayınına bakın.
React 16.3'ten önce, oldukça benzer API sunan ve eski bağlam API'sını kullanan tepki yayınını kullanmanızı öneririm .
Portallar
Normal üst / alt öğedeki gibi basit işlevlerle iletişim kurmalarını sağlamak için 2 bileşeni birbirine yakın tutmak istediğinizde portal kullanın, ancak bu 2 bileşenin DOM'de üst / alt ilişkisi olmasını istemezsiniz, çünkü ima ettiği görsel / CSS kısıtlamaları (z-endeksi, opaklık ... gibi).
Bu durumda bir "portal" kullanabilirsiniz. Genellikle modals , popup, tooltips için kullanılan portalları kullanan farklı reaksiyon kütüphaneleri vardır ...
Aşağıdakileri göz önünde bulundur:
<div className="a">
a content
<Portal target="body">
<div className="b">
b content
</div>
</Portal>
</div>
İçinde işlendiğinde aşağıdaki DOM üretilebilir reactAppContainer
:
<body>
<div id="reactAppContainer">
<div className="a">
a content
</div>
</div>
<div className="b">
b content
</div>
</body>
Daha fazla ayrıntı burada
yuvalar
Bir yerde bir yuva tanımlarsınız ve daha sonra yuvayı oluşturma ağacınızın başka bir yerinden doldurursunuz.
import { Slot, Fill } from 'react-slot-fill';
const Toolbar = (props) =>
<div>
<Slot name="ToolbarContent" />
</div>
export default Toolbar;
export const FillToolbar = ({children}) =>
<Fill name="ToolbarContent">
{children}
</Fill>
Bu, portallara biraz benzer, ancak doldurulmuş içerik tanımladığınız bir yuvada oluşturulurken, portallar genellikle yeni bir dom düğümü oluşturur (genellikle belgenin çocuklarıdır.)
Reaksiyon yuvası doldurma kitaplığını kontrol edin
Etkinlik otobüsü
React belgelerinde belirtildiği gibi :
Ebeveyn-çocuk ilişkisi olmayan iki bileşen arasındaki iletişim için kendi global olay sisteminizi kurabilirsiniz. ComponentDidMount () içindeki olaylara abone olun, componentWillUnmount () öğesinden çıkın ve bir olay aldığınızda setState () öğesini çağırın.
Bir olay veri yolu kurmak için kullanabileceğiniz birçok şey vardır. Sadece bir dizi dinleyici oluşturabilirsiniz ve etkinlik yayınlandığında tüm dinleyiciler etkinliği alır. Veya EventEmitter veya PostalJs gibi bir şey kullanabilirsiniz
Akı
Flux temel olarak bir olay veri yoludur, ancak olay alıcıları mağazalardır. Bu durum, durum React dışında yönetilmesi dışında temel olay veri yolu sistemine benzer
Orijinal Flux uygulaması, Olay kaynağı kullanımını hacky bir şekilde yapma girişimi gibi görünüyor.
Redux benim için olay kaynaklarından en yakın olan Flux uygulamasıdır, zaman yolculuğu yeteneği gibi olay kaynağı avantajlarının çoğuna fayda sağlar. React ile kesin olarak bağlantılı değildir ve diğer işlevsel görünüm kütüphaneleriyle de kullanılabilir.
Egghead'in Redux video eğitimi gerçekten güzel ve dahili olarak nasıl çalıştığını açıklıyor (gerçekten basit).
imleçler
İmleçler ClojureScript / Om'dan geliyor ve React projelerinde yaygın olarak kullanılıyor. React dışındaki durumu yönetmeye izin verir ve bileşen ağacı hakkında hiçbir şey bilmeye gerek kalmadan, birden fazla bileşenin devletin aynı bölümüne okuma / yazma erişimine izin verir.
ImmutableJS , React-ursors ve Omniscient gibi birçok uygulama mevcut
Edit 2016 : İnsanlar imleçlerin daha küçük uygulamalar için iyi çalıştığını kabul ediyor gibi görünüyor, ancak karmaşık uygulamalarda iyi ölçeklenmiyor. Om Next'in artık imleçleri yok (konsepti başlangıçta tanıtan Om olsa da)
Karaağaç mimarisi
Elm mimarisi tarafından kullanılmak üzere önerilen bir mimaridir Elm dili . Elm ReactJS olmasa bile, Elm mimarisi React'te de yapılabilir.
Redux'nun yazarı Dan Abramov, React kullanarak Elm mimarisinin bir uygulamasını yaptı.
Hem Redux hem de Elm gerçekten harika ve ön uçtaki olay kaynağı kavramlarını güçlendirmeye eğilimlidirler, her ikisi de zaman yolculuğu hata ayıklama, geri alma / yineleme, tekrar oynatma ...
Redux ve Elm arasındaki temel fark, Elm'in devlet yönetimi konusunda çok daha katı olma eğilimindedir. Elm'de yerel bileşen durumunuz veya takma / çıkarma kancalarınız olamaz ve tüm DOM değişikliklerinin genel durum değişiklikleri tarafından tetiklenmesi gerekir. Karaağaç mimarisi TÜM durumu tek bir değişmez nesne içinde işlemeye izin veren ölçeklenebilir bir yaklaşım önerirken, Redux sizi tek bir değişmez nesne içinde devletin EN ÇOK ele almaya davet eden bir yaklaşım önerir.
Elm'in kavramsal modeli çok zarif olsa da ve mimari büyük uygulamalarda iyi ölçeklenmesine izin verirken, pratikte zor olabilir veya bir girdiyi monte ettikten sonra odaklanmak veya mevcut bir kütüphaneyle entegre etmek gibi basit görevleri yerine getirmek için daha fazla kaynak içerebilir. zorunlu bir arayüz ile (yani JQuery eklentisi). İlgili konu .
Ayrıca, Elm mimarisi daha fazla kod kaynatma plakası içerir. Yazmak o kadar karmaşık ya da karmaşık değil ama Elm mimarisinin statik olarak yazılmış diller için daha uygun olduğunu düşünüyorum.
CTP
RxJS, BaconJS veya Kefir gibi kütüphaneler, bileşenler arasındaki iletişimi sağlamak için FRP akışları üretmek için kullanılabilir.
Örneğin Rx-React'i deneyebilirsiniz
Bence bu kütüphaneleri kullanmak, ELM dilinin sinyallerle sunduklarını kullanmaya oldukça benzer .
CycleJS çerçevesi ReactJS kullanmaz, ancak vdom kullanır . Elm mimarisi ile birçok benzerlik paylaşır (ancak gerçek hayatta kullanımı daha kolaydır, çünkü vdom kancalarına izin verir) ve işlevler yerine RxJ'leri yaygın olarak kullanır ve FRP ile kullanmak istiyorsanız iyi bir ilham kaynağı olabilir. Tepki. CycleJs Egghead videoları , nasıl çalıştığını anlamak için iyi.
CSP
CSP (Sıralı İşlemleri İletişim Etme) şu anda popülerdir (çoğunlukla Go / goroutines ve core.async / ClojureScript nedeniyle), ancak JS-CSP ile javascript'te de kullanabilirsiniz .
James Long, React ile nasıl kullanılabileceğini açıklayan bir video yaptı .
Sagalar
Destan, DDD / EventSourcing / CQRS dünyasından gelen ve ayrıca "süreç yöneticisi" olarak adlandırılan bir arka plan konseptidir. Bu tarafından popüler olan Redux-Saga çoğunlukla yan etkiler (örneğin, API çağrıları vs.) depolanması için Redux-thunk için bir yedek olarak, proje. Çoğu insan şu anda sadece yan etkilere hizmet ettiğini düşünüyor, ancak aslında daha çok bileşenleri ayırmakla ilgili.
Bu, tamamen yeni bir iletişim sisteminden çok bir Flux mimarisine (veya Redux) iltifattır, çünkü destan sonunda Flux eylemleri yayar. Fikir şudur: widget1 ve widget2'niz varsa ve bunların ayrıştırılmasını istiyorsanız, widget1'den eylem hedefleme widget2'sini tetikleyemezsiniz. Widget1'i yalnızca kendisini hedefleyen eylemleri gerçekleştirirsiniz ve destan, widget1 eylemlerini dinleyen ve widget2'yi hedefleyen eylemler gönderebilen bir "arka plan işlemidir". Efsane, 2 widget arasındaki bağlantı noktasıdır, ancak widget'lar ayrıştırılmış olarak kalır.
Eğer ilgileniyorsanız burada benim cevap bir göz atın
Sonuç
Bu farklı stilleri kullanarak aynı küçük uygulamanın bir örneğini görmek istiyorsanız, bu deponun dallarını kontrol edin .
Uzun vadede en iyi seçeneğin ne olduğunu bilmiyorum ama Flux'un olay kaynağı gibi görünmesini gerçekten çok seviyorum.
Olay kaynağı oluşturma kavramlarını bilmiyorsanız, bu çok pedagojik bloga bir göz atın: Veritabanını apache Samza ile ters çevirerek , Flux'un neden güzel olduğunu anlamak gerekir (ancak bu FRP için de geçerli olabilir) )
Topluluğun en umut verici Flux uygulamasının, sıcak yeniden yükleme sayesinde giderek daha verimli geliştirici deneyimine izin verecek olan Redux olduğunu kabul ettiğini düşünüyorum . Etkileyici canlı kodlama ala Bret Victor'un Prensipte İcat videosu mümkün!