Хорошо, мы могли бы обернуть действие, которое Дети выполняют в Обещание:
function usePromises() {
const promises = useMemo([], []);
const [result, setResult] = useState(undefined);
useEffect(() => { // this gets deferred after the initialization of all childrens, therefore all promises were created already
Promise.all(promises).then(setResult);
}, []);
function usePromise() {
return useMemo(() => {
let resolve;
promises.push(new Promise(r => resolve = r));
return resolve;
}, []);
}
return [result, usePromise];
}
Теперь создайте одного общего менеджера (внутри Родителя):
const [queries, useQueryArrived] = usePromises();
// queries is either undefined or an array of queries, if all queries arrived this component will rerender
console.log(queries);
Затем передайте useQueryArrived
для детей и используйте его там (внутри детей):
const queryArrived = useQueryArrived();
// somewhen:
queryArrived({ some: "props" });
Теперь логика выглядит следующим образом:
Родитель будет визуализирован в первый раз, он создастpromises
массив.Дети будут инициализированы, и каждый из них создаст Обещание, которое присоединяется к promises
распознаватель Обещания запоминается так, что один и тот же распознаватель будет возвращаться при каждом повторном воспроизведении ребенка.Когда все дети были инициализированы, React рендерится и эффект запускается, что примет все обещания и вызовет для них Promise.all
.
Теперь когда-нибудь queryArrived
вызывается у детей, обещания разрешаются, иногдапоследнее выполненное обещание, которое затем вызывает setResult
со всеми результатами обещаний, что приведет к повторному отображению для Родителя, который теперь может использовать запросы.