Flux'ı kullanmak için uygulamamı yeniden yazıyorum ve Mağazalardan veri alma konusunda sorun yaşıyorum. Çok fazla bileşenim var ve çok fazla iç içe geçiyorlar. Bazıları büyük ( Article
), bazıları küçük ve basit ( UserAvatar
, UserLink
).
Mağazalardan verileri bileşen hiyerarşisinde nerede okumam gerektiği konusunda mücadele ediyorum.
İkisini de pek sevmediğim iki aşırı yaklaşımı denedim:
Tüm varlık bileşenleri kendi verilerini okur
Mağazadan bazı verilere ihtiyaç duyan her bileşen yalnızca varlık kimliğini alır ve varlığı kendi başına alır.
Örneğin Article
, geçerarticleId
, UserAvatar
ve UserLink
geçirilir userId
.
Bu yaklaşımın birkaç önemli dezavantajı vardır (örnek kod altında tartışılmıştır).
var Article = React.createClass({
mixins: [createStoreMixin(ArticleStore)],
propTypes: {
articleId: PropTypes.number.isRequired
},
getStateFromStores() {
return {
article: ArticleStore.get(this.props.articleId);
}
},
render() {
var article = this.state.article,
userId = article.userId;
return (
<div>
<UserLink userId={userId}>
<UserAvatar userId={userId} />
</UserLink>
<h1>{article.title}</h1>
<p>{article.text}</p>
<p>Read more by <UserLink userId={userId} />.</p>
</div>
)
}
});
var UserAvatar = React.createClass({
mixins: [createStoreMixin(UserStore)],
propTypes: {
userId: PropTypes.number.isRequired
},
getStateFromStores() {
return {
user: UserStore.get(this.props.userId);
}
},
render() {
var user = this.state.user;
return (
<img src={user.thumbnailUrl} />
)
}
});
var UserLink = React.createClass({
mixins: [createStoreMixin(UserStore)],
propTypes: {
userId: PropTypes.number.isRequired
},
getStateFromStores() {
return {
user: UserStore.get(this.props.userId);
}
},
render() {
var user = this.state.user;
return (
<Link to='user' params={{ userId: this.props.userId }}>
{this.props.children || user.name}
</Link>
)
}
});
Bu yaklaşımın olumsuz yönleri:
- Potansiyel olarak Mağazalara abone olan 100'lerin bileşenlerine sahip olmak sinir bozucu;
- Bu var verilerin güncellenir nasıl ve hangi sırayla takip etmek zor her bileşen bağımsız olarak verileri alır, çünkü;
- Halihazırda durumdaki bir varlığınız olsa bile , kimliğini tekrar alacak (veya tutarlılığı bozacak) çocuklara vermek zorunda kalırsınız.
Tüm veriler en üst düzeyde bir kez okunur ve bileşenlere aktarılır
Hataları izlemekten yorulduğumda, tüm verileri geri getirmeyi en üst seviyeye koymaya çalıştım. Ancak bunun imkansız olduğu kanıtlandı çünkü bazı varlıklar için çeşitli seviyelerde yuvalama var.
Örneğin:
- A
Category
içerirUserAvatar
bu kategoriye katkıda bulunan kişileri ; - Bir
Article
birkaç tane olabilirCategory
.
Bu nedenle, Mağazalardan tüm verileri bir düzeyinde almak Article
istersem, şunları yapmam gerekir:
- Makaleyi şuradan al:
ArticleStore
; - Tüm makalelerin kategorilerini şuradan al:
CategoryStore
; - Her kategorinin katılımcılarını ayrı ayrı şuradan alın:
UserStore
; - Bir şekilde tüm bu verileri bileşenlere aktarın.
Daha da sinir bozucu bir şekilde, derinlemesine iç içe geçmiş bir varlığa ihtiyaç duyduğumda, ek olarak geçmek için her bir yuvalama düzeyine kod eklemem gerekir.
Özetliyor
Her iki yaklaşım da kusurlu görünüyor. Bu sorunu en zarif şekilde nasıl çözerim?
Hedeflerim:
Mağazaların çılgın sayıda abonesi olmamalıdır. Ana bileşenler zaten bunu yapıyorsa, her birinin
UserLink
dinlemesi aptalcaUserStore
.Eğer üst bileşen depodan bir nesne aldıysa (örn.
user
), İç içe geçmiş herhangi bir bileşenin onu tekrar getirmesini istemiyorum. Sahne aracılığıyla geçirebilmeliyim.Tüm varlıkları (ilişkiler dahil) en üst düzeyde getirmek zorunda olmamalıyım çünkü bu, ilişkileri eklemeyi veya kaldırmayı karmaşıklaştırır. İç içe geçmiş bir varlık her yeni ilişki aldığında (örneğin kategori a alır
curator
) tüm yuvalama düzeylerinde yeni sahne tanıtmak istemiyorum .