React.js + video 元素:通过 React 道具设置当前播放时间?

React.js + video element: set current play time from react props?

我刚开始使用 React,这是一个问题,到目前为止我还没有找到很好的解决方案。问题是我想在用户单击按钮时将标签中播放的视频设置到某个位置。

我目前的解决方案如下:

componentDidUpdate(prevProps, prevState) {
    console.log("Updating to timestamp: " + this.props.timestamp);
    var timestamp = this.props.timestamp;
    if (timestamp != prevProps.timestamp) {
        React.findDOMNode(this.refs.theVideo).currentTime = timestamp;
    }
}

问题是,这看起来真的很老套。现在我处于这种情况,用户可以点击同一个按钮两次但什么也不会发生,所以我正在考虑向组件添加更多状态以确保该案例正常工作。

这是正确的做法吗?到目前为止,React 中的一切似乎都非常合乎逻辑,但这感觉不太对。在这种情况下,您会向父级公开子级的方法吗?

您在问题中提到了一个解决方案——您可以在设置时间戳的子项上公开一种方法。但是,这是非常必要的 API,并且可能不适合声明性的应用程序。

在最近的一个项目中,我用声明式 API using componentWillReceiveProps 实现了类似的东西,与您自己的解决方案非常相似:

componentWillReceiveProps: function(props) {
  if (this.props.playing !== props.playing) {
    this.audio[props.playing ? "play" : "pause"]();
  }

  if (this.props.lastSeek !== props.lastSeek) {
    var start = props.start,
        offset = props.currentTime - start;
    this.audio.currentTime = offset / 1000;
  }
}

通过比较上次渲染时给组件的属性和本次给组件的属性,我们可以确定需要调整音频剪辑时间。

我认为最好的解决方案是创建一个特殊的 <Video> 组件,其中 唯一的 工作是将命令式 API 隐藏在声明性 [=29] 后面=];那么,您的应用程序不需要知道命令式 API。因此,在您的应用中,您可以使用

render() {
  // ...
  <Video url={...} timestamp={this.props.timestamp} />
}

您可以了解有关此概念的更多信息 in this meetup talk: "Bridging Imperative APIs with Kinetophone"(大约 7:04)。