我有一个 ts React 应用程序,可以从 mongoDb 中提取一些对象。它们之间有基于 id 的链接,我正在尝试简化关系的遵循方式。
我期望我的状态会产生四个集合,其中填充了对象,这些对象将相互指向对方。我有学生、研讨会、订阅和付款。订阅将学生与研讨会相关联,付款与订阅相关联。我希望能够致电:
a_student.name
// A string
a_student.subscriptions()
// The student's subscriptions
a_student.subscriptions()[0].workshop().subscriptions()
// This students first workshop's subscriptions
a_student.subscriptions()[0].workshop().subscriptions().map(s => s.student().name)
// The names of all of this student's first workshop's fellows
我必须检索原始后端数据,然后“水合”它,在实体之间建立链接。
我有一个
useBackend
钩子,我在其中导出一个提取原始数据的函数和一个 ready
布尔值,它给出绿灯来渲染 UI
我希望根据中间布尔状态
useEffect
.用
dataLoaded
处理补水阶段
问题是我遇到了一个锁定情况,在这种情况下,查找函数在仍然是空列表的情况下被关闭。我想让我的链接查找更新的列表,例如,学生的订阅功能可以获取新学生的订阅,而无需修改学生(这是我正在尝试改进的场景)。
const useBackend = () => {
// State and interface definitions for both cable-data buffer and hydrated elements lists
const pullBackend = async () => {
const raw_students = await pullStudents()
const raw_workshops = await pullWorkshops()
const raw_subscriptions = await pullSubscriptions()
const raw_payments = await pullPayments()
if(!raw_students || !raw_workshops || !raw_subscriptions || !raw_payments) {console.error(`Something went wrong`); return; }
setStudentsBuffer(raw_students)
setWorkshopsBuffer(raw_workshops)
setSubscriptionsBuffer(raw_subscriptions)
setPaymentsBuffer(raw_payments)
setDataLoaded(true)
}
useEffect(() => {
if(dataLoaded){
const getMember = <T>(collection: Collection<T>) =>
(_id: MongoId) => {
console.log(`Looking up _id ${_id} in collection:`)
console.log(collection)
return _.find(collection, e => e._id == _id)
}
getStudent = getMember(students)
getWorkshop = getMember(workshops)
getSubscription = getMember(subscriptions)
getPayment = getMember(payments)
const hydrateStud: Hydrator<StudentCable, Student> = a => ({
...a,
subscriptiones: () => subscriptions.filter(i => i._student == a._id),
payments: () => payments.filter(m => (m.reason == "single class" || m.reason == "subscription") && m._student == a._id)
})
const hydrateSubs: Hydrator<SubscriptionCable, Subscription> = i => ({
...i,
_student: i.student,
_workshop: i.workshop,
student: () => getStudent(i.student)!,
workshop: () => getWorkshop(i.workshop)!,
started: new Date(i.started),
pagos: payments.filter(m => m.reason == "subscription" && m._subscription == i._id)
})
const hydrateWork: Hydrator<WorkshopCable, Workshop> = t => ({
...t,
_subscriptions: t.subscriptions,
subscriptions: () => subscriptions.filter(i => i._workshop == t._id),
started: new Date(t.started)
})
const hydratePaym: Hydrator<PaymentCable, Payment> = m => ({
...m,
_student: m.student,
student: () => getStudent(m.student),
_workshop: m.workshop,
workshop: () => getWorkshop(m.workshop),
date: new Date(m.date),
occasion: new Date(m.occasion)
})
setStudents(studentsBuffer.map(hydrateStud))
setWorkshopes(workshopesBuffer.map(hydrateWork))
setSubscriptiones(subscriptionesBuffer.map(hydrateSubs))
setPayments(paymentsBuffer.map(hydratePaym))
setReady(true)
}
}, [dataLoaded])
}
我可以使用什么机制来延迟集合中的查找直到调用?