ฉันเขียนแอปใหม่เพื่อใช้ Flux และฉันมีปัญหาในการดึงข้อมูลจากร้านค้า ฉันมีส่วนประกอบมากมายและพวกมันก็ทำรังมากมาย บางอันมีขนาดใหญ่ ( Article
) บางอันมีขนาดเล็กและเรียบง่าย ( UserAvatar
, UserLink
)
ฉันกำลังดิ้นรนกับลำดับชั้นขององค์ประกอบที่ฉันควรอ่านข้อมูลจากร้านค้า
ฉันลองสองวิธีที่รุนแรงซึ่งฉันไม่ชอบ:
ส่วนประกอบเอนทิตีทั้งหมดอ่านข้อมูลของตนเอง
ส่วนประกอบแต่ละรายการที่ต้องการข้อมูลบางส่วนจาก Store จะได้รับเพียง ID เอนทิตีและดึงข้อมูลเอนทิตีด้วยตัวเอง
ตัวอย่างเช่นArticle
มีการส่งผ่านarticleId
, UserAvatar
และจะถูกส่งผ่านUserLink
userId
แนวทางนี้มีข้อเสียที่สำคัญหลายประการ (กล่าวถึงภายใต้ตัวอย่างโค้ด)
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>
)
}
});
ข้อเสียของแนวทางนี้:
- เป็นเรื่องน่าผิดหวังที่มีส่วนประกอบ 100s ที่อาจสมัครเป็นสมาชิกร้านค้า
- เป็นการยากที่จะติดตามว่าข้อมูลได้รับการอัปเดตอย่างไรและเรียงลำดับอย่างไรเนื่องจากแต่ละองค์ประกอบดึงข้อมูลอย่างอิสระ
- ถึงแม้ว่าคุณจะอยู่แล้วมีกิจการในรัฐที่คุณถูกบังคับให้ผ่าน ID เพื่อเด็กที่จะดึงมันอีกครั้ง (หรืออื่น ๆ ที่ทำลายความมั่นคง)
ข้อมูลทั้งหมดจะถูกอ่านครั้งเดียวที่ระดับบนสุดและส่งต่อไปยังส่วนประกอบ
เมื่อฉันเบื่อกับการติดตามจุดบกพร่องฉันพยายามให้ข้อมูลทั้งหมดที่ดึงมาอยู่ในระดับบนสุด อย่างไรก็ตามสิ่งนี้พิสูจน์แล้วว่าเป็นไปไม่ได้เพราะสำหรับบางเอนทิตีฉันมีการซ้อนกันหลายระดับ
ตัวอย่างเช่น:
Category
มีUserAvatar
ของคนที่มีส่วนร่วมในหมวดหมู่ที่;Article
อาจมีหลายCategory
s
ดังนั้นหากฉันต้องการดึงข้อมูลทั้งหมดจากร้านค้าในระดับ an Article
ฉันจะต้อง:
- ดึงบทความจาก
ArticleStore
; - ดึงหมวดหมู่บทความทั้งหมดจาก
CategoryStore
; - ดึงข้อมูลผู้มีส่วนร่วมของแต่ละหมวดหมู่จาก
UserStore
; - ส่งผ่านข้อมูลทั้งหมดไปยังส่วนประกอบ
ยิ่งน่าผิดหวังมากขึ้นเมื่อใดก็ตามที่ฉันต้องการเอนทิตีที่ซ้อนกันอย่างลึกซึ้งฉันจะต้องเพิ่มโค้ดในแต่ละระดับของการซ้อนกันเพื่อส่งต่อไป
สรุป
ทั้งสองแนวทางดูเหมือนมีข้อบกพร่อง ฉันจะแก้ปัญหานี้อย่างสง่างามที่สุดได้อย่างไร
วัตถุประสงค์ของฉัน:
ร้านค้าไม่ควรมีจำนวนสมาชิกที่บ้าคลั่ง มันโง่มากที่แต่ละคน
UserLink
จะฟังUserStore
หากส่วนประกอบของผู้ปกครองทำเช่นนั้นหากองค์ประกอบหลักได้ดึงวัตถุบางอย่างจากร้านค้า (เช่น
user
) ฉันไม่ต้องการให้ส่วนประกอบที่ซ้อนกันต้องดึงข้อมูลอีกครั้ง ฉันควรจะส่งผ่านอุปกรณ์ประกอบฉากได้ฉันไม่ควรดึงเอนทิตีทั้งหมด (รวมถึงความสัมพันธ์) ที่ระดับบนสุดเพราะจะทำให้การเพิ่มหรือลบความสัมพันธ์ซับซ้อน ฉันไม่ต้องการแนะนำอุปกรณ์ประกอบฉากใหม่ในทุกระดับการซ้อนทุกครั้งที่เอนทิตีที่ซ้อนกันได้รับความสัมพันธ์ใหม่ (เช่นหมวดหมู่ได้รับ a
curator
)