Redux Thunk’ın Kullanım Amacı

Yunus Ünver
BilgeAdam Teknoloji
3 min readAug 12, 2020

Bu yazımda sürekli React projelerimize eklediğimiz ama sadece ekleyip geçtiğimiz neden kullanıldığını genelde tam olarak bilmediğimiz redux-thunk kütüphanesini anlatmak istiyorum. Bu konuyu şu yüzden anlatmak istedim: “Ekliyoruz ama neden?”. Öncelikle şunu bilmemiz gerekiyor, redux-thunk’ı kullanmamızdaki en temel sebep Reducer’larımızın saf halde kalmasını sağlamaktır. Şimdi izninizle hemen konuya giriyorum. Projelerimizde actionlarımız üzerinden API’a istek attığımız zamanlar oluyor. Bu isteklerimizi asenkron fonksiyonları kullanarak yapıyoruz.

export const getAll = async () => {
var result = await axios(“http://apiadresimiz.com/users”);
return{
type:”Get_All”,
payload:result
}
}

Yukarıdaki gibi bir API’ye istek atan Action’ımız olduğunu varsayalım. Burada bize görünen; belirtilen adresten kullanıcıların bilgilerini bekliyoruz ve dönen sonucu payload’a koyup Reducer’ımıza gönderiyoruz.

Herşey göründüğü gibi mi? Gönderiyor muyuz gerçekten? Bu kodu, projemizde çalıştırdığımız zaman tarayıcıda şöyle bir hatayla karşılaşıyoruz.

Tarayıcı hatası

Normalde Action’larımız javascript objesi geriye dönerler ve Redux’ın anladığı ise bu javascript objeleridir. Bu objelerden kastım zorunlu bir type değeri ve isteğe bağlı payload değeri barındıran objelerdir.

return{
type:”Get_All”, // Zorunlu
payload:result // Opsiyonel
}

Genelde API’ye istek atmadığımızda type ve payload değeri o an için belli olan değerlerdir. Fakat biz API’ye istek attığımız zaman Action’ımız saf olmaktan çıkıyor ve API’den dönen değere göre çıktı üretiyor. Geriye dönen değer javascript objesi olmadığı için Redux bunu anlayamıyor. Tarayıcı da çıkan hata da şöyle diyor; “Bak sen asenkron bir Action tanımlamışsın, eğer asenkron kullanmaya devam edeceksen burada middleware kullan, ben senden geriye içinde type parametresi bulunan bir javascript objesi bekliyorum, sen bana fonksiyon dönüyorsun” diyor. Bizde “Eee ama obje dönüyorum… Kod yukarda işte…” derken o da şöyle bir cevap ile geliyor “ Hani biz EcmaScript 6 standartlarına göre kod yazıyoruz ya… Sonra bizim yazdığımız kodu Babel ES6’ dan ES5’e çeviriyor… Orada obje dönmüyor işte.” diyip Babel’ın Compiler’ına gidip kodumuzun ES5 haline bakıyoruz.

while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return axios("http://apiadresimiz.com/users");
case 2:
result = _context.sent;
return _context.abrupt("return", {
type: "Get_All",
payload: result
});
case 4:
case "end":
return _context.stop();
}
}

Ve burada görüldüğü gibi redux’ın kafası karışıyor, geriye axios ile API’a yaptığımız istek dönüyor. Ama bizim istediğimiz(yani actionun istediği) ve bize ES6’da görünen şekliyle bir javascript objesi dönmesiydi.

Redux-thunk’ı eklediğimiz zaman Action’ınımız artık bir Middleware’den geçecek ve gelen cevaba göre hareket edecek. Yani bu saatten sonra Action içerisinde geriye fonksiyon dispatch ettiğimiz zaman devreye redux-thunk girecek ve fonksiyon döndükçe “sen bi fonksiyonun cevabını bekle eğer cevap hazırsa gelen cevabı dispatch edip Reducer’a yollarız” diyip yoluna devam edecek . Kodumuz aşağıdaki şekilde:

export const getAll = () => {
return async (dispatch) => {
var result = await axios("http://apiadresimiz.com/users");
dispatch({
type:"Get_All",
payload:result
})
}
}

Gelelim o zaman async kullanmadığımızda neler oluyor? Kendimize şu soruyu sorabiliriz “İyi madem async kullanınca kızıyo o zaman kullanmayalım, ne gerek var yani? “. Tamam kullanmayalım hatada vermez, proje çalışır. Ne gerek var o zaman bu kadar kütüphane ekleyeyim de araya bir tane katman koyayım bizim isteğimiz gelene kadar beklesin de ondan sonra dispatch etsin? Şu yüzden gerek var, bizim isteğimizin ne zaman geleceği belli değil, sunucunun yoğunluğuna göre 1 saniyede de gelebilir 10 saniyede de gelebilir. Böyle olunca Action’ımız cevabı beklemeden dönecek ve Payload’ın içine gelen cevabı atamamış yani boş bir değer atamış olacağız. Artık sonucu ekranda veya console’da bekliyorsak boş bir sayfa bizi karşılayacak. Bu yüzden middleware kullanarak cevap geldiğinde dispatch işlemini gerçekleştir demiş oluyoruz.

https://babeljs.io/ adresinden try it out kısmında kodunuzu EcmaScript 5'e çevirebilirsiniz.

--

--