YouTube埋め込みプレーヤーのあるページでhistoryに同一URLがpushされる

何が起こった?

  • YouTube埋め込みプレーヤーを使っているページで同一のURLがhistoryにpushされていた。つまりページAからYouTube埋め込みプレーヤーのあるページBに遷移し動画の読み込みが完了した後に「前のページに戻る」操作をしてもそこは同じページBであり、二回戻る操作をしなければいけなくなった。
  • React、React Router

なぜ起こった?

  • 以下のようにiframeのsrcにyoutube_video_idを渡しているが、このyoutube_video_idはAPIを叩いて取得した値である。つまり初めはnullで、APIの結果が返ってくると実際の値が入る。
  • 初めは<iframe src={null}>APIの結果が返ってくると<iframe src={"https://..."}>という感じでiframe内のURLが変化している。この変化によって前述の問題が発生していた。
const PageB =() => {
  const { youtube_video_id } = useSelector(state => state.hoge);
  return (
    <div>
        <iframe
          title={"youtube" +youtube_video_id}
          src={"https://www.youtube.com/embed/" + youtube_video_id}
          frameborder="0"
          allowfullscreen
        ></iframe>
    </div>
  );
}

どう直した?

  • つまりは正しいyoutube_video_idが手に入るまではiframe自体を描画しなければいいので以下のようにした。
const PageB = () => {
  const { youtube_video_id } = useSelector(state => state.hoge);
  
  if (youtube_video_id == null) {
    return (
      <div>読み込み中...</div>
    );
  }

  return (
    <div>
        <iframe
          title={"youtube" + youtube_video_id}
          src={"https://www.youtube.com/embed/" + youtube_video_id}
          frameborder="0"
          allowfullscreen
        ></iframe>
    </div>
  );
}

気をつける点

  • これはiframeのsrcがnullからあるURLに変化したから起こったバグであるが、もしPageB -> 他のページ -> PageBという流れで移動したときに一回目のPageBのyoutube_video_idと二回目のPageBのyoutube_video_idが違う場合に注意が必要である。PageBがアンマウントされた時にStore内のyoutube_video_idをnullで初期化しておかないと今回の問題と全く同じ問題が発生する。

参考

stackoverflow.com