Thunk-redux (санка)

redux-thunk (“санка”) – это функция, позволяющая выполнять несколько асинхроннных операций. Её можно диспатчить в store, где она сама потом диспатчит в него экшены.

Функцию thunk запускает сам store (redux), куда мы ее и диспатчим. Точнее ее запускает “прослойка” thunk midleware, которую нужно установить между store и редьюсерами. Эта прослойка пропускает экшены дальше в редьюсеры, а функцию thunk она “распаковывает” – хранящиеся в ней экшны снова направляет в storeа, а другие санки (если они есть внутри этой санки) тоже “распапковываются” и так циклами, пока все распакованые экшены передадутся в редьюсеры.

Напоминание. Редьюсеры – это чистые функции в отдельных файлах, созданные для каждой компоненты (если ей нужа связь со стором), которые поочередно каждый принимают экшены, и кому из них экшен подошел, тот возвращает новый стейт.
А экшены – это объекты, которые имеют как минимум свойство type, по которому редьюсеры и понимают, что нужно сделать.

Чем санки полезны?

Санки дают возможность избежать общения UI с DAL, а также передавать несколько экшенов сразу и выполнять асинхронные операции.

Установка thunk-redux

npm i redux-thunk

Применение

  1. applyMiddleware – это предложенный библиотекой redux способ добавления усилитей, т.е. различных Middleware. Middleware – это всегда функция, которые обычно возвращают функцию, если только целью middleware не является прервать цепочку вызовов. В файле redux-store импортируем applyMiddleware из redux и наш “усилитель” – промежуточный уровень (прокладку) thunkMiddleware  между store и reducers:
    import { createStore, combineReducers, applyMiddleware } from "redux";
    import thunkMiddleware from 'redux-thunk';
  2. Добавляем функцию applyMiddleware с параметром thunkMiddleware туда, где мы объявляли store с редьюсерами, т.е. параметром к функции createStore. Получается вот так:
    let store = createStore(reducers, applyMiddleware(thunkMiddleware));
  3. В файле reducer нужной компоненты (например, users-reducer.js) создаем и экспортируем саму санку, что напоминает работу с экшн-криэйтерами:
    export const getUsersThunkCreator = (currentPage, pageSize) => {
    
       return (dispatch) => {
            dispatch (toogleIsFetching(true));
    
            usersAPI.getUsers(currentPage, pageSize).then(data => {
                    dispatch(toogleIsFetching(false));
                    dispatch(setUsers(data.items)); 
                    dispatch(setTotalUsersCount(data.totalCount)); 
                });
        }
    }
  4. В контейнерной компоненте в connect закидываем эту санку рядом с экшн-криэйтерами, например:
    export default connect (mapStateToProps, {follow, unfollow, setUsers, getUsersThunkCreator}) (UsersContainer);
  5. Вызываем внутри контейнерной компоненты из пропсов колбек санки. Например, внутри componentDidMount и дальше в коде (конечно же, еще и экспортируем эту сверху функцию сверху):
    class UsersContainer extends React.Component {
    
        componentDidMount() {
            this.props.getUsers(this.props.currentPage, this.props.pageSize);     
        }
    
        onPageChanged = (pageNumber) => {
            this.props.getUsers(pageNumber, this.props.pageSize);
        }
        
        
        render() { 
         .......

    Само название функции санок делается более простым (в даном случае можно просто getUsers),  а здесь оно более длинное для облегчения понимания.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *