Jef*_*ley 5 flux reactjs reactjs-flux refluxjs
虽然我的场景非常具体,但我认为它在Flux中提出了一个更大的问题.组件应该是来自商店的简单数据呈现,但是如果组件呈现有状态的第三方组件会怎样?如何在遵守Flux规则的同时与第三方组件进行交互?
所以,我有一个包含视频播放器的React应用程序(使用clappr).一个很好的例子就是寻求.当我点击进度条上的某个位置时,我想要寻找视频播放器.这就是我现在所拥有的(使用RefluxJS).我试图将我的代码删除到最相关的部分.
var PlayerActions = Reflux.createActions([
'seek'
]);
var PlayerStore = Reflux.createStore({
listenables: [
PlayerActions
],
onSeek(seekTo) {
this.data.seekTo = seekTo;
this.trigger(this.data);
}
});
var Player = React.createClass({
mixins: [Reflux.listenTo(PlayerStore, 'onStoreChange')],
onStoreChange(data) {
if (data.seekTo !== this.state.seekTo) {
window.player.seek(data.seekTo);
}
// apply state
this.setState(data);
}
componentDidMount() {
// build a player
window.player = new Clappr.Player({
source: this.props.sourcePath,
chromeless: true,
useDvrControls: true,
parentId: '#player',
width: this.props.width
});
},
componentWillUnmount() {
window.player.destroy();
window.player = null;
},
shouldComponentUpdate() {
// if React realized we were manipulating DOM, it'd certainly freak out
return false;
},
render() {
return <div id='player'/>;
}
});
Run Code Online (Sandbox Code Playgroud)
我对此代码的错误是当你试图两次寻找同一个地方时.想象一下视频播放器在不断播放.点击进度条进行搜索.不要移动鼠标,等待几秒钟.再次点击与之前相同位置的进度条.值data.seekTo没有改变,因此window.player.seek不是第二次调用.
我已经考虑过一些解决这个问题的可能性,但我不确定哪个更正确.请求输入...
1:seekTo使用后复位
简单地重置seekTo似乎是最简单的解决方案,尽管它肯定不再优雅.最终,这更像是一个创可贴.
这就像......一样简单
window.player.on('player_seek', PlayerActions.resetSeek);
Run Code Online (Sandbox Code Playgroud)
2:创建一个单独的商店,更像是一个传递
基本上,我会听一个SeekStore,但实际上,这将作为一个传递,使它更像一个商店的行动.这个解决方案感觉就像是Flux的黑客,但我认为它会起作用.
var PlayerActions = Reflux.createActions([
'seek'
]);
var SeekStore = Reflux.createStore({
listenables: [
PlayerActions
],
onSeek(seekTo) {
this.trigger(seekTo);
}
});
var Player = React.createClass({
mixins: [Reflux.listenTo(SeekStore, 'onStoreChange')],
onStoreChange(seekTo) {
window.player.seek(seekTo);
}
});
Run Code Online (Sandbox Code Playgroud)
3:window.player在我的行动中互动
当我考虑它时,这感觉是正确的,因为呼叫window.player.seek实际上是一种行为.唯一奇怪的是,我感觉不适合window与行动内部互动.也许这只是一种非理性的想法.
var PlayerActions = Reflux.createActions({
seek: {asyncResult: true}
});
PlayerActions.seek.listen(seekTo => {
if (window.player) {
try {
window.player.seek(seekTo);
PlayerActions.seek.completed(err);
} catch (err) {
PlayerActions.seek.failed(err);
}
} else {
PlayerActions.seek.failed(new Error('player not initialized'));
}
});
Run Code Online (Sandbox Code Playgroud)
顺便说一句,房间里还有另一头大象,我没有碰过.在我的所有示例中,播放器都存储为window.player.Clappr在旧版本中自动执行此操作,但虽然已经修复了与Browserify一起使用,但我们继续将其存储在window(技术债务)上.显然,我的第三个解决方案是利用这个事实,从技术上来说这是一件坏事.无论如何,在任何人指出,理解和注意之前.
4:寻求通过 dispatchEvent
我也明白,派遣一个自定义事件可以完成工作,但考虑到我有Flux,这感觉有点不对劲.这感觉就像我要在我的Flux架构之外完成工作.我应该能够做到并留在Flux游乐场内.
var PlayerActions = Reflux.createActions({
seek: {asyncResult: true}
});
PlayerActions.seek.listen(seekTo => {
try {
let event = new window.CustomEvent('seekEvent', {detail: seekTo});
window.dispatchEvent(event);
PlayerActions.seek.completed(err);
} catch (err) {
PlayerActions.seek.failed(err);
}
});
var Player = React.createClass({
componentDidMount() {
window.addEventListener('seekEvent', this.onSeek);
},
componentWillUnmount() {
window.removeEventListener('seekEvent', this.onSeek);
},
onSeek(e) {
window.player.seek(e.detail);
}
});
Run Code Online (Sandbox Code Playgroud)
5:保持演奏位置处于状态(如丹·考夫曼所述)
可以这样做:
handlePlay () {
this._interval = setInterval(() => this.setState({curPos: this.state.curPos + 1}), 1000)
this.setState({playing: true}) // might not be needed
}
handlePauserOrStop () {
clearInterval(this._interval)
this.setState({playing: false})
}
componentWillUnmount () {
clearInteral(this._interval)
}
onStoreChange (data) {
const diff = Math.abs(data.seekTo - this.state.curPos)
if (diff > 2) { // adjust 2 to your unit of time
window.player.seek(data.seekTo);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
788 次 |
| 最近记录: |