質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

iframe

HTMLのタグ<iframe>です。<iframe>は、ドキュメント内に""inline frame""を作るHTML要素で、同じページでセパレートしているドキュメントが表示されるようにします。

ページネーション

Webアプリケーションにおいて、1ページに収まらないコンテンツを、各ページへのリンクを並べてアクセスしやすくする手法をページネーションと呼びます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

1803閲覧

【React】ページ切り替え後、vimeo APIで表示したiframeの中身が切り替わらない・再描画できない

yooonb

総合スコア17

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

iframe

HTMLのタグ<iframe>です。<iframe>は、ドキュメント内に""inline frame""を作るHTML要素で、同じページでセパレートしているドキュメントが表示されるようにします。

ページネーション

Webアプリケーションにおいて、1ページに収まらないコンテンツを、各ページへのリンクを並べてアクセスしやすくする手法をページネーションと呼びます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2021/07/06 09:50

編集2021/07/06 15:15

追記

質問をしてから、気付きました。
iframeが表示されないのは、stateで管理されていないからかもしれません。
iframeにstateして、再描画できるようにしてみます。

→ うまくいかない。

どうやら、
前の <Vimeo /> をアンマウントする前に、次の <Vimeo /> がマウントされているのが原因?


前提・実現したいこと

実現したいこと
ページネーションでのページ切り替え時に、
vimeoのiframeの中身が切り替わらないため、
切り替えて表示させたいです。

前提

  • react
  • ページネーションは、@material-uiを使用。
  • firebase realtime database

表示しているリストのデータについて

  • リストを全件取得
  • リストを分割してページごとに出し分け

発生している問題・エラーメッセージ

  • 画面上でだけ、iframeの中身が変更されない。
  • videoIdの変更は、コンポーネントに渡って来ている。

該当のソースコード

vimeoを表示している部分

js

1// Vimeo.js 2import React, { useEffect, useState } from 'react' 3import Player from "@vimeo/player" 4import { itemRef } from '../../firebase' 5 6export const Vimeo = (props) => { 7 const { videoId, item } = props 8 const uploadState = !!item.videoUploaded 9 const [uploaded, setUploaded] = useState(uploadState) 10 11 const iframeId = `vimeo-${videoId}` 12 13 // vimeoのアップロードが完了したか確認 14 // アプロード完了フラグは、DBで管理 15 const check = (player) => { 16 if (!uploaded) { 17 player.getVideoUrl().then((url) => { 18 console.log('動画のURL;', url); 19 setUploaded(true) 20 itemRef.child(item.key).update({videoUploaded: true}) 21 }).catch((error) => { 22 console.log('error', error, videoId); 23 }) 24 } 25 } 26 27 // マウント時・uploaded変更時に実行 28 useEffect(() => { 29 const options = { id: videoId } 30 31 // vimeo player 作成 32 const player = new Player(iframeId, options) 33 console.log("player", player) // 切り替わっている 34 35 // 最初に1回実行 36 check(player) 37 38 let time = null 39 // タイマーでアップロード済みか確認 40 if (!uploaded) { 41 time = setInterval(() => { check(player) }, 60000) 42 } else { 43 clearInterval(time) 44 } 45 46 // アンマウント時にタイマークリア 47 return () => clearInterval(time) 48 }, [uploaded, videoId]) 49 50 return ( 51 <div 52 className="embed-container" 53 style={{ width: '100%' }} 54 > 55 <div id={iframeId}>{/* ここのidは、ページ切替時に正常に変更される */} 56 {/* Playerにより、ここにiframeが表示される¥ */} 57 {/* ↓ 表示されるiframeは、こんな感じ。ここが変更されない。 58 <iframe 59 src="https://player.vimeo.com/video/00000?title=0&amp;byline=0&amp;portrait=0&amp;app_id=xxxxx" 60 width="640" height="360" 61 frameborder="0" 62 allow="autoplay; fullscreen; picture-in-picture" 63 allowfullscreen="" 64 title="xxxxxxxx" 65 data-ready="true"> 66 </iframe> 67 */} 68 </div> 69 </div> 70 ) 71} 72

投稿1つ分、表示部分

js

1// Item.js 2import React, { useEffect } from 'react' 3import { Card } from '@material-ui/core' 4import withWidth, { isWidthUp } from '@material-ui/core/withWidth' 5import { Vimeo } from './common/Vimeo' 6 7const Item = React.memo((props) => { 8 const { content } = props 9 const { key, video } = content 10 11 // video id 取得 12 const uri = video.url // https://vimeo.com/manage/videos/00000000 13 const pos = uri.lastIndexOf('/') 14 const videoId = uri.slice(pos + 1) // 00000000 15 16 return ( 17 <Card id={`item-${key}`}> 18 <p>ここにビデオが表示されます</p> 19 <Vimeo videoId={videoId} item={content} /> 20 </Card > 21 ) 22}) 23export default withWidth()(Item)

一覧ページ

js

1// Lists.js 2import React, { useState, useEffect, useContext } from 'react' 3import { List } from '@material-ui/core' 4import Pagination from '@material-ui/lab/Pagination' 5import Item from './Item' 6import { GlobalContext } from '../../hooks/reducer' 7import { itemRef } from '../../firebase' 8 9const Lists = React.memo((props) => { 10 const { state: { sample }, dispatch } = useContext(GlobalContext) 11 const { list } = sample 12 13 // ページの設定 14 const [page, setPage] = useState(1) 15 const [totalPages, setTotalPages] = useState(0) 16 const perPage = 20 17 const startNum = (page - 1) * perPage 18 19 useEffect(() => { 20 // マウント時にリストを全件取得 21 itemRef 22 .orderByKey() 23 .on('value', (snapshot) => { 24 const lists = snapshot.val() 25 if (lists === null) { return dispatch({ type: 'SET_LISTS', data: [] }) } 26 const newLists = Object.entries(lists).map((entry) => { 27 const [key, content] = entry 28 return { key, ...content } 29 }) 30 dispatch({ type: 'SET_LISTS', data: newLists }) 31 }) 32 }, []) 33 34 useEffect(() => { 35 // ページ数を取得 36 setTotalPages(Math.ceil(list.length / perPage)) 37 }, [list]) 38 39 return ( 40 <div> 41 <List> 42 { 43 list.length > 0 && ( 44 list.slice(startNum, startNum + perPage).map((content, key) => { 45 return <Item content={content} /> 46 }) 47 ) 48 } 49 </List> 50 51 {/* ページネーション */} 52 { list.length > 0 && <Pagination count={totalPages} size="large" page={page} onChange={(e, newPage) => setPage(newPage)} /> } 53 </div > 54 ) 55}) 56export default Lists

listのデータ構造

js

1list = [ 2 { 3 "key": "xxxx", 4 "video": { 5 "url": "/videos/000000" 6 }, 7 "videoUploaded": true 8 }, 9 // ... 10]

試したこと

マウント時にiframeをリロードすればいいと思い、実装しましたが、それもうまくいきません。
おそらく、読み込み完了前のためです。

エラー

TypeError: Cannot read property 'location' of undefined

js

1// Vimeo.js 2 3 // iframeをreloadする 4 const reloadIframe = (iframeId) => { 5 // フレームのDOM要素を取得 6 const target = document.getElementById(iframeId) 7 // フレームをreload 8 target.contentWindow.location.reload(true) 9 } 10 11 useEffect(() => { 12 // ....省略 13 14 reloadIframe(iframeId) 15 16 return () => clearInterval(time) 17 }, [uploaded, videoId])

onloadは効きませんでした。

js

1 const reloadIframe = (iframeId) => { 2 const target = document.getElementById(iframeId) 3 target.onload = (e) => { 4 // そもそもここに来ない 5 console.log("onloaded") 6 target.contentWindow.location.reload(true) 7 } 8 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

・動的にiframeを作成
・iframeIdが変更されたとき、iframe内のsrcを変更sる
iframeElement.src = "xxxxx"

<div id={iframeId}></div>

投稿2021/09/13 10:29

yooonb

総合スコア17

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問