#reactjs
#reactjs
Вопрос:
У меня есть родительский компонент с двумя кнопками. Кнопка 1 должна открывать iFrame с URL 1, а кнопка 2 — url 2. Кажется, что, как я его построил, iFrame не перестраивается полностью.
parent.js
if (currentTable.id === "Bo3Ko3K") {
<DailyCo url="https://meeting.daily.co/123456" />
} else if (currentTable.id === "9RGmWxX") {
<DailyCo url="https://meeting.daily.co/abcdef" />
}
child.js
import { makeStyles } from "@material-ui/core/styles";
import React, { useRef, useEffect } from "react";
import DailyIframe from "@daily-co/daily-js";
const useStyles = makeStyles((theme) => ({
root: {
width: "100%",
height: "100vh",
border: "0",
},
}));
const DailyCo = ({ url }) => {
const classes = useStyles();
const iframeRef = useRef();
useEffect(() => {
if (!url) {
console.error("please set an url!");
return;
}
const daily = DailyIframe.wrap(iframeRef.current, {
// showLeaveButton: true,
});
daily.join({ url });
}, [url]);
return (
<iframe
className={classes.root}
title="video call iframe"
ref={iframeRef}
allow="camera; microphone; fullscreen"
></iframe>
);
};
export default DailyCo;
Комментарии:
1. Добавьте ключ к элементам DailyCo или к iframe, который отличается в зависимости от URL.
2. Привет, Захари, я уже пробовал это, но это не решило проблему, несмотря на разные ключи.
3. Не могли бы вы подробнее остановиться на проблеме, с которой вы столкнулись? Ключи гарантируют, что компонент отключается / перемонтируется, как показано здесь: codesandbox.io/s/elastic-microservice-i80p6?file=/src/App.js
4. Большое спасибо за codesandbox! Я использовал его, чтобы проиллюстрировать проблему: loom.com/share/9a2458c3ed394266808d85194df64733 Вы можете увидеть там, что при новой загрузке страницы все работает идеально. Однако, как только я переключаю roomId, видео издателя (слева внизу) исчезает. В консоли это выглядит так, что другие IFRAME просто добавляются в оверлей, но не заменяются полностью. Вот ваша версия с готовыми к использованию идентификаторами таблиц: codesandbox.io/s/sharp-wu-7gpgd?file=/src/App.js Ожидаемое поведение заключается в том, что издатель в левом нижнем углу всегда появляется при переключении комнаты.
Ответ №1:
У вас есть 2 варианта, которые я вижу, чтобы заставить это работать:
- Вам нужно покинуть собрание, прежде чем присоединиться к новому. К сожалению, этот метод усложняется тем, что ежедневно требуется около 7 мс (асинхронно), чтобы покинуть собрание. Таким образом, невозможно просто
useEffect
выполнить обычную очистку. Это также забавно, потомуdaily.leave()
что возвращает обещание, которое никогда не выполняется, если вы не на собрании. Их документация вleave()
настоящее время вводит в заблуждение:
Покидает собрание. Если встречи нет, этот метод ничего не делает.
Возвращает null;
https://codesandbox.io/s/reverent-grass-qpjke?file=/src/App.js
const iframeRef = useRef();
const dailyRef = useRef();
const joinedRef = useRef();
useEffect(() => {
dailyRef.current = DailyIframe.wrap(iframeRef.current, {
// showLeaveButton: true,
});
dailyRef.current.on('left-meeting',()=>{
joinedRef.current=false;
})
dailyRef.current.on('joining-meeting',()=>{
joinedRef.current=true
})
console.log("mounted");
return () => {
dailyRef.current.destroy();
console.log("unmount");
};
}, []);
useEffect(() => {
(async () => {
if (joinedRef.current) {
// This is needed due to it never returning
// if there wasn't a meeting joined first...
await dailyRef.current.leave();
}
if (!url) {
console.error("please set an url!");
return;
}
await dailyRef.current.join({ url });
})();
}, [url]);
- Вам нужно позвонить
daily.destroy()
перед созданием нового переноса, иначе они мешают друг другу, возникают проблемы, и новый никогда не устанавливается полностью. Эта проблема описана в их документации дляdestroy
Вы можете повторно использовать iframe вызова daily-js или объект вызова несколько раз (последовательность вызовов методов join(), leave(), join() И т. Д. Будет работать нормально).
Но когда вы закончите с объектом вызова daily-js, вы должны вызвать destroy(), чтобы освободить все связанные с ним ресурсы.
Это особенно важно, если вы планируете создать еще один объект daily-js в будущем. Если вы не вызовете destroy(), а позже создадите новый объект вызова daily-js, прослушиватели событий из старого объекта и нового объекта будут мешать друг другу.
https://codesandbox.io/s/spring-water-nv3k3?file=/src/App.js
const iframeRef = useRef(null);
useEffect(() => {
if (!url) {
console.error("please set an url!");
return;
}
const daily = DailyIframe.wrap(iframeRef.current, {
// showLeaveButton: true,
});
daily.join({ url });
return () => {
daily.destroy();
};
}, [url]);
В общем, я бы рекомендовал использовать вариант 1 хотя бы потому, что он более производительный (меньше настроек и времени, необходимых для смены собраний). Хотя проще просто уничтожить перенос и воссоздать его.
Комментарии:
1. Вау, не знаю, что сказать. Это решило все. Большое вам спасибо! Я выберу вариант 1.
2. Привет, Захари, у меня есть еще один дополнительный вопрос. При добавлении второй кнопки я столкнулся с другой проблемой: loom.com/share/e9b03203fe42458f8b0abd44d250517b Как только я нажимаю на «AnotherComponent» при ежедневной загрузке, появляется сообщение об ошибке «Не удалось выполнить ‘removeChild’ «. У вас есть какие-либо идеи, как это исправить? Я создал следующую изолированную среду: codesandbox.io/s/blazing-darkness-5qp77?file=/src/App.js
3. Спасибо за проверку 🙂 На самом деле я решил это немного по-другому и вместо этого использовал событие «joined-meeting». Это также решило проблему: codesandbox.io/s/blazing-darkness-5qp77?file=/src/App.js
4. Однако я уже сталкиваюсь со следующей проблемой. Если я быстро и в нужный момент переключаюсь между идентификаторами, я получаю сообщение об ошибке: «ошибка: не удается изменить daily.co вызовите URL-адрес после загрузки () «. loom.com/share/65ac66985b474518aabf60a94277df7a Если у вас есть какие-либо идеи, я был бы вам очень признателен.
5. Я думаю, добавив
joiningRef
вместе с. leave() при переключении решил это сейчас: codesandbox.io/s/quirky-forest-qc8yj?file=/src/App.js:586-596