é possível despachar uma ação no próprio redutor? Eu tenho uma barra de progresso e um elemento de áudio. O objetivo é atualizar a barra de progresso quando a hora for atualizada no elemento de áudio. Mas não sei onde colocar o manipulador de eventos ontimeupdate ou como despachar uma ação no retorno de chamada de ontimeupdate para atualizar a barra de progresso. Aqui está o meu 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 isso não deveria ser algo no estado.Respostas:
Despachar uma ação dentro de um redutor é um antipadrão . Seu redutor deve estar sem efeitos colaterais, simplesmente digerindo a carga útil da ação e retornando um novo objeto de estado. Adicionar ouvintes e enviar ações no redutor pode levar a ações encadeadas e outros efeitos colaterais.
Parece que sua
AudioElement
classe inicializada e o ouvinte de eventos pertencem a um componente e não ao estado. No ouvinte de eventos, você pode despachar uma ação, que será atualizadaprogress
no estado.Você pode inicializar o
AudioElement
objeto de classe em um novo componente React ou apenas converter essa classe em um componente React.Observe que ele
updateProgressAction
é automaticamente empacotadodispatch
para que você não precise ligar diretamente para o envio.fonte
MyAudioPlayer
componente do contêiner paiconnect
editado comreact-redux
. Veja como fazer issomapDispatchToProps
aqui: github.com/reactjs/react-redux/blob/master/docs/…updateProgressAction
definido no seu exemplo?redux-thunk
está despachando uma ação de outra ação, não o redutor. stackoverflow.com/questions/35411423/…Iniciar outro despacho antes que o redutor seja concluído é um antipadrão , porque o estado que você recebeu no início do redutor não será mais o estado atual do aplicativo quando o redutor terminar. Mas agendar outro despacho de dentro de um redutor NÃO é um antipadrão . De fato, é isso que a linguagem Elm faz e, como você sabe, o Redux é uma tentativa de trazer a arquitetura Elm para o JavaScript.
Aqui está um middleware que adicionará a propriedade
asyncDispatch
a todas as suas ações. Quando o redutor terminar e retornar o novo estado do aplicativo,asyncDispatch
será acionadostore.dispatch
com qualquer ação que você der a ele.Agora seu redutor pode fazer isso:
fonte
dispatch
que devem retornar a ação. Alterei as últimas linhas para:const res = next(actionWithAsyncDispatch); syncActivityFinished = true; flushQueue(); return res;
e funcionou muito bem.Você pode tentar usar uma biblioteca como redux-saga . Ele permite uma maneira muito limpa de sequenciar funções assíncronas, acionar ações, usar atrasos e muito mais. É muito poderoso!
fonte
supplier
informações quando o usuário tentar acessar aitem
página de detalhes. VocêcomponentDidMount()
dispararia uma função que despacha uma ação, digamosFETCH_SUPPLIER
. Dentro do redutor, você pode marcar algo como aloading: true
para mostrar um botão giratório enquanto a solicitação é feita.redux-saga
ouviria essa ação e, em resposta, dispararia a solicitação real. Utilizando funções de gerador, ele pode esperar a resposta e despejá-laFETCH_SUPPLIER_SUCCEEDED
. O redutor atualiza a loja com informações do fornecedor.O redux-loop pega uma sugestão de Elm e fornece esse padrão.
fonte