使用React更新HTML5视频上的源URL

She*_*way 21 javascript video html5 reactjs

我想更新HTML5视频元素中的源标记,这样当我点击一个按钮时,无论播放什么都会切换到新视频.

我有一个Clip组件,它返回一个HTML5视频元素,源URL通过props提供.

function Clip(props) {
  return (
    <video width="320" height="240" controls autoPlay>
      <source src={props.url} />
    </video>
  )
}
Run Code Online (Sandbox Code Playgroud)

我还有一个Movie组件,它包含多个URL,每个URL对应一部分电影.它还包含一个position属性,它通过记住当前正在播放的部分来充当迭代器.

class Movie extends Component {
  constructor() {
    super();
    this.state = {
      sections: [
        'https://my-bucket.s3.amazonaws.com/vid1.mp4',
        'https://my-bucket.s3.amazonaws.com/vid2.mp4'
      ],
      position: 0
    };
  }
  render() {
    const sections = this.state.sections
    const position = this.state.position

    return (
      <div>
        {position}
        <Clip url={sections[position]} />
        <button onClick={() => this.updatePosition()}>Next</button>
      </div>
    )
  }
  updatePosition() {
    const position = this.state.position + 1;
    this.setState({ position: position });
  }
}
Run Code Online (Sandbox Code Playgroud)

Movie组件呈现Clip组件和"Next"按钮.单击"下一步"按钮时,我想更新位置属性,并使用部分中的下一个URL重新呈现HTML5视频元素.

截至目前,当我点击下一步HTML5视频源标签更新,但该元素继续播放上一个URL中的视频.任何人都可以帮我弄清楚如何重置视频元素?

更新:我创建了一个JSFiddle,你可以在这里看到.

更新2:更新视频元素上的src属性有效!

Ram*_*zar 63

简短的awnser:添加key道具<Clip><video>,例如:

function Clip({ url }) {
  return (
    <video key={url}>
      <source src={url} />
    </video>
  );
}
Run Code Online (Sandbox Code Playgroud)

Long awnser:视频不会改变,因为实质上你只修改了<source>元素而React知道它<video>应该保持不变,因此它不会在DOM上更新它,也不会load为该源触发新事件.

为了确保不仅要<source>更新,而且还要<video>添加一个key道具,以便React了解这是一个全新的元素.

有关更完整的说明,请查看有关React docs上的键的文章 :)

  • 我认为这应该是公认的答案. (7认同)
  • 我希望我能对此再投票。 (3认同)
  • 感谢您快速学习更改检测。:) (3认同)
  • 对于打字稿使用 `const videoRef = useRef&lt;HTMLVideoElement&gt;(null);`。 (2认同)

Mar*_*son 16

<source />由于某种原因,更改src 似乎不会切换视频.这不是我不认为的反应问题.可能只是如何<source />运作.也许你必须.load()再次调用该元素.但是直接在元素本身上设置它会更容易.

请参阅顶部答案的评论:我可以使用javascript动态更改视频的来源吗?

您可以src直接在元素上设置:

function Clip(props) {
  return (
    <video width="320" height="240" src={props.url} controls autoPlay>
    </video>
  )
}
Run Code Online (Sandbox Code Playgroud)