Рендеринг iFrame в React

#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 варианта, которые я вижу, чтобы заставить это работать:

  1. Вам нужно покинуть собрание, прежде чем присоединиться к новому. К сожалению, этот метод усложняется тем, что ежедневно требуется около 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]);
 

  1. Вам нужно позвонить 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