Сама запись просто укороченный способ записать функцию которая возвращает функцию, которая возвращает функцию.
function logger(store) {
return function wrapDispatchToAddLogging(next) {
return function dispatchAndLog(action) {
console.log('action', action)
console.log('next', next)
console.log('store', store)
return next
}
}
}
Легче читается так
const logger = store => next => action => {
console.log('action', action)
console.log('next', next)
console.log('store', store)
return next
}
И вызвав
logger(1)(2)(3);
вы получете:
action 3
next 2
store 1
Далее, сама applyMiddleware уже умеет(с проверками и парочкой хитростей и ограничениями) прокидывать нужные параметры, запуская каждый middlware, на каждом этапе добавляя параметр.
Условный пример, не про реальность, а так чтобы понятно:
//Наш миддлвар
const logger = store => next => action => {
console.log('action', action)
console.log('next', next)
console.log('store', store)
return next
}
//другой наш миддлвар
const logger2 = store => next => action => {
console.log('action2', action)
console.log('next2', next)
console.log('store2', store)
return next
}
//Наша функция применялка, которая берет все миддлвары и будет с ними что-то мутить
function applyMiddleware(...middlewares) {
const param1 = 1;
const param2 = 2;
const param3 = 3;
const do1 = middlewares.map(middleware => middleware(param1))
const do2 = do1.map(middleware => middleware(param2))
const do3 = do2.map(middleware => middleware(param3))
//Возвращаем условно
return 1
}
//Где-то в коде мы вызываем applyMiddleware
applyMiddleware(logger, logger2 )
//В консоле получим
//action 3
//next 2
//store 1
//action2 3
//next2 2
//store2 1