A sample action creator (e.g., setColorTheme):
export const setColorTheme = (colorTheme: string): LoggedUserAction => ({ type: LoggedUserActionType.LOGGED_USER__SET_COLOR_THEME, colorTheme });
export const setColorTheme = (colorTheme: string): LoggedUserAction => ({ type: LoggedUserActionType.LOGGED_USER__SET_COLOR_THEME, colorTheme });
increaseOrderQuantity(item) { const itemIndex = this.state.data.indexOf(item); this.setState(({data}) => ({ data: [ ...data.slice(0, itemIndex), { ...item, quantity: item.quantity + 1 }, ...data.slice(itemIndex + 1) // have made a mistake of forgetting to include + 1 ] })); }
import produce from 'immer'; . . . increaseOrderQuantity(item) { const itemIndex = this.state.data.indexOf(item); this.setState(produce(draft => { draft.data[itemIndex].quantity++; })); }
export const incrementCounter = (n?: number): CounterAction => ({ type: CounterActionType.COUNTER__INCREMENT, n }); const mapDispatchToProps = (dispatch: Dispatch) => ({ incrementCounter: (n?: number) => dispatch(incrementCounter(n)), getLoggedUser: async () => { const userRequest = await fetch('https://jsonplaceholder.typicode.com/users/1'); const {status} = userRequest; if (!(status === 200 || status === 301)) { throw new Error('HTTP Status: ' + status); } const {username} = await userRequest.json() as IUserDto; await dispatch(setLoggedUser(username)); await dispatch(setColorTheme('blue')); } }); export default connect(mapStateToProps, mapDispatchToProps)(hot(App));
export const incrementCounter = (n?: number): CounterAction => ({ type: CounterActionType.COUNTER__INCREMENT, n }); export const getLoggedUser = () => async (dispatch: Dispatch): Promise<void> => { const userRequest = await fetch('https://jsonplaceholder.typicode.com/users/1'); const {status} = userRequest; if (!(status === 200 || status === 301)) { throw new Error('HTTP Status: ' + status); } const {username} = await userRequest.json() as IUserDto; await dispatch(setLoggedUser(username)); await dispatch(setColorTheme('blue')); }; const actionCreators = { incrementCounter, getLoggedUser }; export default connect(mapStateToProps, actionCreators)(hot(App));
Uncaught Error: Actions must be plain objects. Use custom middleware for async actions.
import { applyMiddleware, compose, createStore, Store } from 'redux'; import { reducersRoot } from './reducers-root'; import { IAllState } from './all-state'; import ReduxThunk from 'redux-thunk'; export function configureStore(): Store<IAllState> { const middlewares = applyMiddleware(ReduxThunk); const composeEnhancers = (window as any)['__REDUX_DEVTOOLS_EXTENSION_COMPOSE__'] || compose; const composed = composeEnhancers(middlewares); return createStore(reducersRoot(), composed); }
const actionCreators = { incrementCounter, getLoggedUser };
const actionCreators = { incrementCounter: (n?: number) => incrementCounter(n! * 42), getLoggedUser };
import { createStore, Store } from 'redux'; import { reducersRoot } from './reducers-root'; import { IAllState } from './all-state'; export function configureStore(): Store<IAllState> { const devTools: any = (window as any)['__REDUX_DEVTOOLS_EXTENSION__']; return createStore(reducersRoot(), devTools && devTools()); }
import { applyMiddleware, compose, createStore, Store } from 'redux'; import { reducersRoot } from './reducers-root'; import { IAllState } from './all-state'; import ReduxThunk from 'redux-thunk'; export function configureStore(): Store<IAllState> { const middlewares = applyMiddleware(ReduxThunk); const composeEnhancers = (window as any)['__REDUX_DEVTOOLS_EXTENSION_COMPOSE__'] || compose; const composed = composeEnhancers(middlewares); return createStore(reducersRoot(), composed); }
// file 1 export interface ILoggedUserState { username: string; email: string; lastLogged: Date; } // file 2 export interface IAllState { loggedUser: ILoggedUserState; chosenTheme: IChosenTheme; menu: IMenu; } // file 3 interface IPropsToUse { loggedUser: ILoggedUserState; chosenTheme: IChosenTheme; } export const mapStateToProps = ({loggedUser, chosenTheme}: IAllState): IPropsToUse => ({ loggedUser, chosenTheme });
interface IPropsToUse { username: string; chosenTheme: IChosenTheme; } export const mapStateToProps = ({loggedUser: {username}, chosenTheme}: IAllState): IPropsToUse => ({ username, chosenTheme });
interface IPropsToUse { username: ILoggedUserState['username']; chosenTheme: IChosenTheme; } export const mapStateToProps = ({loggedUser: {username}, chosenTheme}: IAllState): IPropsToUse => ({ username, chosenTheme });