Reputation: 113
I am having problems when I execute some async functions inside the store. For my application, I am using React, Redux and Typescript
If you look below, I execute a fetch and then I dispatch 3 functions.
First: activate the message visibility to true; Second: to change the text message; Third: to deactivate the message visibility after 5 seconds (async function)
.then(response => {
if (response.ok) {
dispatch({ type: 'LOGIN' });
} else {
return response.json().then(data => {
dispatch({ type: 'TOGGLE_VISIBILITY'});
dispatch({ type: 'MESSAGE_ALERT', payload: data.detail});
dispatch(hideMessageAlert()); // Dispatching the new action creator
});
}
})
However I got this kind of error when I write the third dispatch
"Argument of type '(dispatch: Dispatch) => void' is not assignable to parameter of type 'AnyAction'."
This is my code from my store.tsx and the types.tsx. Is there something that I should do?
import { configureStore, Dispatch } from '@reduxjs/toolkit';
import { AppState } from './types';
import { AnyAction } from 'redux';
// data()
const initialState: AppState = {
loggedIn: false,
isVisible: false,
messageAlert: '',
};
// methods()
interface Action extends AnyAction {
type: 'LOGIN' | 'LOGOUT' | 'TOGGLE_VISIBILITY' | 'MESSAGE_ALERT';
payload?: string | boolean
}
// Adding a new action creator that dispatches a TOGGLE_VISIBILITY action with false payload after 5 seconds
const hideMessageAlert = () => (dispatch: Dispatch<Action>) => {
setTimeout(() => {
dispatch({ type: 'TOGGLE_VISIBILITY', payload: false });
}, 5000);
};
function rootReducer(state = initialState, action: Action): AppState {
switch (action.type) {
case 'LOGIN':
return {
...state,
loggedIn: true,
};
case 'LOGOUT':
return {
...state,
loggedIn: false,
};
case 'TOGGLE_VISIBILITY':
console.log(action.payload);
return {
...state,
isVisible: !state.isVisible,
};
case 'MESSAGE_ALERT':
return {
...state,
messageAlert:`${action.payload}`,
};
default:
return state;
}
}
const store = configureStore({
reducer: rootReducer,
preloadedState: initialState,
});
export { hideMessageAlert, store,};
types.tsx
export interface AppState {
loggedIn: boolean;
isVisible: boolean;
messageAlert: string;
}
Upvotes: 0
Views: 94
Reputation: 7530
If you can't write that any other way, the only solution I see is accepting an action of type Action | (dispatch: Dispatch) => void
function rootReducer(
state = initialState,
action: Action | (dispatch: Dispatch) => void
): AppState {
// ...
}
Or you could just call the setTimeout inside the promise chain:
.then(response => {
if (response.ok) {
dispatch({ type: 'LOGIN' });
} else {
return response.json().then(data => {
dispatch({ type: 'TOGGLE_VISIBILITY'});
dispatch({ type: 'MESSAGE_ALERT', payload: data.detail});
setTimeout(() => {
dispatch({ type: 'TOGGLE_VISIBILITY', payload: false });
}, 5000);
});
}
})
Upvotes: 1