javascript - await - Acciones asincrónicas en Redux
redux-promise (3)
Tengo una aplicación React. Necesito hacer una llamada ajax (para aprender) a un servicio en línea (asincrónico) con Redux.
Esta es mi tienda:
import { createStore, applyMiddleware } from ''redux'';
import thunk from ''redux-thunk'';
import duedates from ''./reducers/duedates''
export default applyMiddleware(thunk)(createStore)(duedates);
Estas son las acciones:
import rest from ''../Utils/rest'';
export function getDueDatesOptimistic(dueDates){
console.log("FINISH FETCH");
console.log(dueDates);
return {
type: ''getDueDate'',
dueDates
}
}
export function waiting() {
console.log("IN WAIT");
return {
type: ''waiting''
}
}
function fetchDueDates() {
console.log("IN FETCH");
return rest({method: ''GET'', path: ''/api/dueDates''});
}
export function getDueDates(dispatch) {
console.log("IN ACTION");
return fetchDueDates().done(
dueDates => dispatch(getDueDatesOptimistic(dueDates.entity._embedded.dueDates))
)
}
Y este es el reductor:
export default (state = {}, action) => {
switch(action.type) {
case ''getDueDate'':
console.log("IN REDUCER")
return state.dueDates = action.dueDates;
default:
return state
}
}
No entiendo lo que estoy haciendo mal. La acción se llama perfectamente desde el componente. Pero luego me sale este error:
Error: las acciones deben ser objetos simples. Use middleware personalizado para acciones asíncronas.
Supongo que estoy usando mal el middleware reaction-thunk. ¿Qué estoy haciendo mal?
EDITAR
Ahora la acción llama al reductor, pero el reductor, después de cambiar el estado, no está volviendo a ejecutar el método de renderizado
case ''getDueDate'':
console.log("IN REDUCER")
return state.dueDates = action.dueDates;
Creo que deberías usar la función de compose
, así que es como
import {
createStore,
applyMiddleware,
compose
} from ''redux'';
import thunk from ''redux-thunk'';
import duedates from ''./reducers/duedates''
export default compose(applyMiddleware(thunk))(createStore)(duedates);
Thunk permite que un creador de acción devuelva una función en lugar de un objeto simple, por lo que la usa como
export function getDueDates() {
return dispatch => {
console.log("IN ACTION");
fetchDueDates().done(
dueDates => dispatch(getDueDatesOptimistic(dueDates.entity._embedded.dueDates))
)
};
}
Estabas devolviendo un objeto Promesa, esa era una parte del problema. Otra parte fue que redux-thunk no se ha aplicado correctamente. Apuesto a que compose
debería resolver el problema.
Creo que es posible tener una solución de trabajo sin usar la función de compose
también. Basado en la documentación del repositorio de GitHub para redux-thunk
La solución funciona para redux-thunk: ^2.0.0
import { createStore, applyMiddleware } from ''redux'';
import thunk from ''redux-thunk'';
import duedates from ''./reducers/duedates''
export function configureStore(initialState = {}) {
return createStore(
duedates,
initialState,
applyMiddleware(thunk)
);
}
La respuesta aceptada es desactualizada, incorrecta o complicada. Aquí están los documentos sobre el tema de composición:
http://redux.js.org/docs/api/compose.html
para que podamos hacerlo así en su lugar:
import {createStore, combineReducers, compose, applyMiddleware} from ''redux'';
import thunk from ''redux-thunk'';
const reducer = combineReducers({
user: userReducer,
items: itemsReducer
});
// here is our redux-store
const store = createStore(reducer,
compose(applyMiddleware(thunk))
);