¿Es posible despachar una acción en un reductor? Tengo una barra de progreso y un elemento de audio. El objetivo es actualizar la barra de progreso cuando el tiempo se actualiza en el elemento de audio. Pero no sé dónde colocar el controlador de eventos ontimeupdate, ni cómo enviar una acción en la devolución de llamada de ontimeupdate, para actualizar la barra de progreso. Aquí está mi código:
//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;
AudioElement
? Parece que eso no debería ser algo en estado.Respuestas:
El envío de una acción dentro de un reductor es un antipatrón . Su reductor no debe tener efectos secundarios, simplemente digiere la carga útil de la acción y devuelve un nuevo objeto de estado. Agregar oyentes y enviar acciones dentro del reductor puede conducir a acciones encadenadas y otros efectos secundarios.
Parece que su
AudioElement
clase inicializada y el detector de eventos pertenecen a un componente en lugar de estar en estado. Dentro del detector de eventos puede enviar una acción, que se actualizaráprogress
en estado.Puede inicializar el
AudioElement
objeto de clase en un nuevo componente React o simplemente convertir esa clase en un componente React.Tenga en cuenta que
updateProgressAction
se envuelve automáticamente, pordispatch
lo que no necesita llamar al despacho directamente.fuente
MyAudioPlayer
componente desde el contenedor principal con el que seconnect
editareact-redux
. Mira cómo hacerlomapDispatchToProps
aquí: github.com/reactjs/react-redux/blob/master/docs/…updateProgressAction
define el símbolo en tu ejemplo?redux-thunk
está enviando una acción de otra acción, no del reductor. stackoverflow.com/questions/35411423/…Iniciar otro despacho antes de que termine su reductor es un antipatrón , porque el estado que recibió al comienzo de su reductor ya no será el estado actual de la aplicación cuando finalice su reductor. Pero programar otro envío desde un reductor NO es un antipatrón . De hecho, eso es lo que hace el lenguaje Elm, y como saben, Redux es un intento de llevar la arquitectura Elm a JavaScript.
Aquí hay un middleware que agregará la propiedad
asyncDispatch
a todas sus acciones. Cuando su reductor haya finalizado y devuelto el nuevo estado de la aplicación,asyncDispatch
se activarástore.dispatch
con cualquier acción que le dé.Ahora su reductor puede hacer esto:
fuente
dispatch
cual, que deberían devolver la acción. Cambié las últimas líneas a:const res = next(actionWithAsyncDispatch); syncActivityFinished = true; flushQueue(); return res;
y funcionó muy bien.Puede intentar usar una biblioteca como redux-saga . Permite una forma muy limpia de secuenciar funciones asíncronas, disparar acciones, usar retrasos y más. Es muy poderoso!
fuente
supplier
información cuando el usuario intenta visitar laitem
página de detalles. TucomponentDidMount()
dispararías una función que despacha una acción, por ejemploFETCH_SUPPLIER
. Dentro del reductor, puede marcar algo como aloading: true
para mostrar una rueda giratoria mientras se realiza la solicitud.redux-saga
escucharía esa acción y, en respuesta, dispararía la solicitud real. Utilizando las funciones del generador, puede esperar la respuesta y volcarlaFETCH_SUPPLIER_SUCCEEDED
. El reductor luego actualiza la tienda con información del proveedor.redux-loop toma una señal de Elm y proporciona este patrón.
fuente