
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
});