когда нечего делать, а творческая душа требует реализации и хочется что-то сделать или написать, то я пишу сюда или делаю что-то на этом сайте. Кому интересна web-разработка, wordpress и то что рядом с этим, то заходите на мой сайт и читайте всякое...
Зачем нужен redux-thunk. Где его использовать, а где можно обойтись и без него
Йо-йо. Так как я сейчас работаю frontend-разработчиком и пишу свой код на react’е мне приходится работать и с redux, чтобы хранить данные и как-то их изменять. Конечно же изменение этих данных влечёт новый рендер.
Из-за того, что данных бывает очень много и, порой, нужно сделать множество преобразований за одно действие, причём изменить данные или запросить их на сервере простого redux не хватает. Приходится пользоваться middleware redux-thunk. В этой статье я хочу поделиться своим опытом использования redux-thunk, рассказать где без него не обойтись, а где для лучшего UX его миновать.
Что такое middleware
Это какая-то функция, которая берёт текущий store, текущий action и что-то делает с этим. Более подробно лучше прочитать в документации.
Redux-thunk — это как раз такая функция, которая, что-то делает со store.
Зачем использовать redux-thunk
Если вы задались этим вопросом, значит вы уже пользуетесь redux и знаете, что обычно action является простым объектом, который используется в reduser, a action creator имеет примерно такой вид:
В данном примере данные будут переданы в переменной array, эти данные и получит reduser и передаст в store.
Пример 1
В примере выше всё очень просто, но часто мы ещё не имеем ни каких данных и их нужно запросить с сервера. Тут то нам и нужен middleware для того, чтобы вызвать dispatch в то время, когда данные уже будут получены. Тогда наш action creator примет такой вид:
В этой функции мы явно вызываем dispatсh, в тот момент, когда мы получим данные.
Пример 2
Кроме того, что мы не имеем данных, бывает, что нужно вызвать сразу несколько action’ов. Например вы хотите сделать ваш компонент неактивным, пока идёт запрос. Вы можете сделать несколько вызовов dispatch в одном экшене.
В данном примере в начале я вызываю другой action creator (setDetouchStadia), делаю запрос на сервер и в любом случает вызываю его заново.
Пример 3
Иногда за одно действие может быть вызвано огромное количество изменений. Сейчас (декабрь 2019) я работаю над плеером для музыки 8bit. Как у любого плеера у него есть пульт для управления треками и список треков, которые можно выбрать. В момент выбора трека мне нужно сделать множество действий, и знать кое-какие данные из store.
Как я уже говорил redux-thunk, как и другие middleware даёт нам доступ к store:
Как может показаться, каждый раз, когда мы используем запросы к серверу мы должны использовать его… А вот и нет.
Хороший пример у меня был совсем недавно в статье про getDerivedStateFromProps. Там говорилось об отмене подписке на уведомления. Там использовался хук реакта и state компонента для изменения состояния подписки и ожидание нового значения из store. Но можно пойти другим путём.
По сути нам нужно было изменить в redux данные об элемент, но если бы мы отправили запрос на сервер в action и ждали ответ сервера то казалось бы, что наш сайт тормозит. Следовательно нам нужно изменить данные и отослать запрос на сервер. И так
// Список автомобилей в store, я примера хватит
[
{CarId: 1, subscribe: true},
{CarId: 2, subscribe: true},
{CarId: 3, subscribe: true},
{CarId: 4, subscribe: true}
]
// action creator
export const unsubscribe = (CarId) => ({
type: UNSUBSCRIBE,
payload:CarId
})
// Reduser, который вызывает функцию unsubscribeFn во время нашего action и возвращает её результат
const carListReduser = (state = [], action) => {
switch(action.type){
case UNSUBSCRIBE:
return unsubscribeFn(state, action.payload);
.......
default:
return state;
}
}
// Функция
export const unsubscribeFn = (state, CarId) => {
const newState = [...state.map(car)=>{
if(car.CarId === CarId){
car.subscribe = false;
}
return car;
})];
const sendData = new FormData();
sendData.append('CarId', CarId );
axios.post('/ajax/unsubscribe', sendData);
return newState;
};
Как вы видите здесь не подразумевалось получение важных данных с сревера. По-этому лучше тут не использовать middleware если оно не нужно. Вполне возможно, что у вас есть только подобные случаи в приложении и не нужно увеличивать бандл без необходимости.
Ещё пример
Иногда нам нужно изменить данные опираясь на state и не нужно получать весь, store целиком. В этом случае тоже можно отказаться от thunk а за место него использовать функции в самом reduser’е. Как я показал выше.
............
case UNSUBSCRIBE:
return unsubscribeFn(state, action.payload);
..............
P.S.
Про react и redux стало на статью больше. Если вы не согласны с моим мнение то можете написать своё в комментариях. А если согласны то не постесняйтесь поддержать проект денежкой)
Поддержи Xakplant
Я давно хочу развить видеоверсию, но пока этого не получается из-за нехватки ресурсов. Сейчас я собираю деньги на новый компьютер и микрофон. Поддержи xaklant и ты увидишь полезные видео быстрее.