【问题标题】:HTML Video tag not updating source on re renderHTML 视频标签在重新渲染时不更新源
【发布时间】:2019-12-05 16:22:54
【问题描述】:

我有一个渲染 2 个 <video> 元素的反应组件。

在任何时候只有 1 个元素是可见的,并且有一些更新状态的逻辑,所以这些切换。

我有一个 id 数组,在每次渲染状态/播放器切换时,我想用随机视频更新正在播放的视频。

(为了这个问题,我添加了一个按钮来切换状态)

如果我在渲染方法中注销我的状态,我可以看到 url 属性按预期更新,但视频不会更改源。

我选择将元素的visibility 切换为display:none 或类似的东西

{playerOne.visible &&
    <LandingPageVideoPlayer url={playerOne.url} />
}

在重新渲染状态时会导致闪烁。

我不知道如何在重新渲染时更改视频元素的来源。

组件

const LandingPageVideoPlayer = ({ url, isActive }) => {
  const playerClassName = `video-player ${isActive ? 'video-player--is-active' : null}`

  return (
    <video className={playerClassName} autoPlay loop muted>
      <source src={url} type='video/mp4' />
    </video>
  )
}
class LandingPage extends Component {

  MOCK_URL_SOURCE = [
    'ehZqNokVylyWk',
    'hDqq4LalRAUiQ',
    'yjTccXlnh6LXW',
    '3FjEPbKqEPhPpmC8uY',
    '3ohs7NLUXtNW98mtIQ'
  ]

  state = {
    playerOne: {
      visible: true,
      url: `https://media0.giphy.com/media/3ohs7NLUXtNW98mtIQ/giphy.mp4`
    },
    playerTwo: {
      visible: false,
      url: `https://media0.giphy.com/media/3FjEPbKqEPhPpmC8uY/giphy.mp4`
    }
  }

  randomItem = () => {
    return this.MOCK_URL_SOURCE[Math.floor(Math.random() * this.MOCK_URL_SOURCE.length)]
  }

  toggle = () => {
    this.setState(prevState => ({
      playerOne: { visible: !prevState.playerOne.visible, url: `https://media0.giphy.com/media/${this.randomItem()}/giphy.mp4` },
      playerTwo: { visible: !prevState.playerTwo.visible, url: `https://media0.giphy.com/media/${this.randomItem()}/giphy.mp4` }
    }))
  }

  render() {
    const { playerOne, playerTwo } = this.state

    if (!playerOne || !playerTwo) {
      return null
    }

    return (
      <div className='landing-page'>
        <button onClick={this.toggle}></button>
        <LandingPageVideoPlayer url={playerOne.url} isActive={playerOne.visible} />
        <LandingPageVideoPlayer url={playerTwo.url} isActive={playerTwo.visible} />
      </div>
    )
  }
}

export default LandingPage

视频播放器 SCSS

  .video-player {
    position: absolute;
    object-fit: cover;
    width: 100%;
    height: 100vh;
    visibility: hidden;

    &--is-active {
      visibility: visible;
    }
  }

【问题讨论】:

    标签: javascript reactjs html5-video


    【解决方案1】:

    React 不知道要更新哪个视频,除非为每个视频提供了 key 属性。

    因此,当您将视频的 key prop 设置为独特的东西时,例如将 url 传递给播放器,它应该可以工作。

    const LandingPageVideoPlayer = ({ url, isActive }) => {
      const playerClassName = `video-player ${
        isActive ? "video-player--is-active" : null
      }`;
    
      return (
             ..... ? .....
        <video key={url} className={playerClassName} autoplay loop muted>
          <source src={url} type="video/mp4" />
        </video>
      );
    };
    

    查看工作演示。

    有关 key 属性如何工作的更多信息,请查看官方文档List and Keys

    第一句话是,

    键帮助 React 识别哪些项目已更改、添加或删除。应为数组内的元素赋予键,以使元素具有稳定的身份

    在你的情况下,你有两个视频(实际上是两个项目的列表),所以为了帮助 React 哪个视频发生了变化,key 将帮助 React 识别哪个视频发生了变化。

    【讨论】:

    • 完美 :) 非常感谢,这完全有道理
    【解决方案2】:

    像这样添加 key={this.state.url}

    <div className="container">
                    <div className="row">
                        <div className="col-8">
                            <video width="720" key={this.state.url} height="540" controls >
                                <source src={this.state.url} type="video/mp4" />
    
                            </video>
                            <h1>{this.state.url}</h1>
    

    【讨论】:

      猜你喜欢
      • 2011-07-27
      • 2022-11-11
      • 2016-12-30
      • 2016-02-20
      • 2017-12-13
      • 1970-01-01
      • 2017-01-23
      • 2021-07-27
      • 1970-01-01
      相关资源
      最近更新 更多