是否可以在减速机本身发送动作?我有一个进度条和一个音频元素 . 目标是在音频元素中更新时间时更新进度条 . 但是我不知道将ontimeupdate事件处理程序放在何处,或者如何在ontimeupdate的回调中调度一个动作来更新进度条 . 这是我的代码:
//reducer
const initialState = {
audioElement: new AudioElement('test.mp3'),
progress: 0.0
}
initialState.audioElement.audio.ontimeupdate = () => {
console.log('progress', initialState.audioElement.currentTime/initialState.audioElement.duration);
//how to dispatch 'SET_PROGRESS_VALUE' now?
};
const audio = (state=initialState, action) => {
switch(action.type){
case 'SET_PROGRESS_VALUE':
return Object.assign({}, state, {progress: action.progress});
default: return state;
}
}
export default audio;
4 回答
Dispatching an action within a reducer is an anti-pattern . 您的reducer应该没有副作用,只需消化动作有效负载并返回一个新的状态对象 . 在reducer中添加侦听器和调度操作可能会导致链接操作和其他副作用 .
听起来像是初始化的
AudioElement
类,事件监听器属于组件而不是状态 . 在事件监听器中,您可以调度一个操作,该操作将更新状态中的progress
.您可以在新的React组件中初始化
AudioElement
类对象,也可以只将该类转换为React组件 .请注意
updateProgressAction
会自动用dispatch
包装,因此您无需直接调用dispatch .Starting another dispatch before your reducer is finished is an anti-pattern ,因为当您的减速器完成时,您在减速器开始时收到的状态将不再是当前的应用状态 . 但 scheduling another dispatch from within a reducer is NOT an anti-pattern . 事实上,这就是Elm语言所做的,正如您所知道的,Redux是尝试将Elm架构引入JavaScript .
这是一个中间件,它将属性
asyncDispatch
添加到您的所有操作中 . 当您的reducer完成并返回新的应用程序状态时,asyncDispatch
将触发store.dispatch
,无论您给它做什么操作 .现在你的减速机可以做到这一点:
您可以尝试使用像redux-saga这样的库 . 它允许以非常简洁的方式对异步函数进行排序,触发操作,使用延迟等 . 它非常强大!
redux-loop从Elm获得提示并提供此模式 .