javascript - useEffect 在 useFrameApi onReady 事件中不起作用

标签 javascript reactjs youtube-api

我尝试使用 useEffect Hook 动态更改视频的 url,并且我不想使用第三方库,所以我完成了这个脚本,当我更改 url 时,youtubeId 状态很好更新,但没有新视频已加载到播放器中。

import React, { useEffect, useState } from "react";

const Y = () => {
  const [youtubeId, setYoutubeId] = useState("ZPt9dJw1Dbw");

  useEffect(() => {
    if (!window.YT) {
      // If not, load the script asynchronously
      const tag = document.createElement("script");
      tag.src = "https://www.youtube.com/iframe_api";

      // onYouTubeIframeAPIReady will load the video after the script is loaded

      window.onYouTubeIframeAPIReady = loadVideo;

      const firstScriptTag = document.getElementsByTagName("script")[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    } else {
      loadVideo();
    }

    function loadVideo() {
      console.log(youtubeId);
      let player = new window.YT.Player(`youtube-player-${youtubeId}`, {
        videoId: youtubeId,
        events: {
          onReady: (event) => {
            event.target.playVideo();
            event.target.loadVideoById({
              videoId: youtubeId
            });
          }
        }
      });
    }
    //
  }, [youtubeId]);

  const foo = () => {
    setYoutubeId("ZrNqjSCfL8E");
  };

  return (
    <div>
      <div id={`youtube-player-${youtubeId}`} />
      <button onClick={foo}>change video</button>
    </div>
  );
};

export default Y;

最佳答案

您已经正确完成了大部分工作。如果您通过 youtube Iframe api,它们会设置全局 var。这意味着你必须做一些改变。

  1. 在外部定义player变量。
  2. 根据您的代码,它将重试在变量中设置new window.YT.Player 对象,但这不是 Iframe api 的工作方式。一旦它在您的 player 对象中设置。它将提供另一个 useFull 函数来执行此操作(您可以在其中找到文档)。

完整代码如下:

import { useEffect, useState, useCallback } from "react";
import "./styles.css";
// import React, { useEffect, useState } from "react";
let player;

const Y = () => {
  const [youtubeId, setYoutubeId] = useState("ZPt9dJw1Dbw");

  useEffect(() => {
    if (!window.YT) {
      // If not, load the script asynchronously
      const tag = document.createElement("script");
      tag.src = "https://www.youtube.com/iframe_api";

      // onYouTubeIframeAPIReady will load the video after the script is loaded

      window.onYouTubeIframeAPIReady = loadVideo;

      const firstScriptTag = document.getElementsByTagName("script")[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    } else {
      loadVideo();
    }

    function loadVideo() {
      if (!player) {
        player = new window.YT.Player(`youtube-player-${youtubeId}`, {
          videoId: youtubeId,
          events: {
            onReady: (event) => {
              event.target.playVideo();
              event.target.loadVideoById({
                videoId: youtubeId
              });
            }
          }
        });
      }
      if (player && player.loadVideoById) {
        player.loadVideoById({ videoId: youtubeId });
      }
    }
    //
  }, [youtubeId]);

  const foo = () => {
    setYoutubeId("ZrNqjSCfL8E");
  };

  return (
    <div>
      <div id={`youtube-player-${youtubeId}`} />
      <button onClick={foo}>change video</button>
    </div>
  );
};

export default function App() {
  return (
    <div className="App">
      <Y />
    </div>
  );
}

这是演示:https://codesandbox.io/s/async-smoke-084n6

关于javascript - useEffect 在 useFrameApi onReady 事件中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66184819/

相关文章:

git - 如何将一个 vendor block 文件(webpack)用于多个 react 项目

youtube - 什么是观众YouTube分析API报告中的百分比-受众特征数据

javascript - Java - Rest 端点返回图像(如果可用)和 JSON(如果不可用)

Javascript/JQuery 填充数组许多元素

javascript - 使用 socket.io 进行客户端实时更新

android - Android 播放器的自定义媒体播放器控件

youtube - 如何使用YouTube数据API在特定位置获取自特定日期以来上传的YouTube视频以及观看次数?

javascript - 仅通过 id 引用元素,没有 document.getElementById

css - HTML/CSS 选择选项悬停 (React)

reactjs - 如何将 react-google-places-autocomplete 与 react-hook-from 集成?