React, kullanıcı arayüzleri geliştirmek için kullanılan bir javascript kütüphanesidir.
Geliştirme yaparken nodejs'e ihtiyaç duyar. Bu yüzden node.js'in geliştirme yapılan cihazda kurulu olması gerekir.
İşletim sistemine uygun olan versiyonunu buradan indirerek normal bir program kurar gibi kurabilirsiniz.
Kurduğunuzdan emin olmak için kurulum sonrası terminalinizi açıp şu komutu çalıştırarak testini yapabilirsiniz:
node -vEğer versiyonu görüyorsanız başarılı olmuşsunuzdur.
Not:
WindowsortamınaNodeJSkurmuş olanlar terminal olarak hali hazırda mevcut olanPowerShelli ya da biraz daha gelişmiş olan Cmder terimalini kurarak testini yapabilir.
Node.js ile bir javascript dosyasını çalıştırmak için şu komutu kullanmanız yeterli;
node <dosya_yolu>Burada <dosya_yolu> yerine sizin oluşturduğunuz javascript dosyasının yolunu vereceksiniz. Örneğin;
node ./index.jsNPM, açılımındanda anlaşılacağı üzere nodejs'in paket yöneticisidir. Buradan kullanmak istediğiniz paketleri npm yardımıyla projenize kurabilir, yönetebilirsiniz.
NPM ile bir paket yüklemek için şu komut kullanılır:
npm install <paket_adi>
# kısa hali
npm i <paket_adi>Bazı durumlarda kuracağınız paketleri projenize özel değilde global olarak kurmanız gerekebilir. Bu durumda global kurulum yapmak için -g flag'ı eklenir.
npm install -g <paket_adi>
# kısa hali
npm i -g <paket_adi>NPM ile bir paketi kaldırmak için şu komut kullanılır:
npm uninstall <paket_adi>Global olarak kurulan bir paketi kaldırmak içinde yine -g flag'ı kullanılır.
npm uninstall -g <paket_adi>Paketler zamanla güncellendiği için projenizde kullandığınız paketleri güncellemek isteyebilirsiniz. Eğer topluca bir güncelleme yapmak isterseniz şu komutu kullanabilirsiniz:
npm updateEğer global olarak kurduğunuz tüm paketleri güncellemek isterseniz -g flag'ı eklemeniz gerekir.
npm update -gEğer belirli bir paketi güncellemek isterseniz şu komutu kullanabilirsiniz:
npm update <paket_adi>Eğer global olarak kurduğunuz belirli bir paketi güncellemek isterseniz de yine -g flag'ı eklemelisiniz.
npm update -g <paket_adi>package.json dosyası javascript/node projenizin ana dizininde bulunan bir JSON dosyasıdır. Projeye ait üst bilgileri ve projenin bağımlılıklarını, scriptlerini, versiyonunu vb. bilgileri tutar.
Bunun farklı yolları vardır. Eğer otomatik oluşturmak isterseniz şu komutu çalıştırarak sizden istenen bilgileri doldurarak oluşturabilirsiniz:
npm initya da -y flag'ı ile varsayılan değerlerle bilgi doldurmadan hızlıca oluşturabilirsiniz:
npm init -yya da dilerseniz hiç terminali işin içine karıştırmadan projenin kök dizininde package.json adıyla bir dosya oluşturup zorunlu alanları ekleyebilirsiniz. Zorunlu alanlar name ve version alanlarıdır.
{
"name": "proje-adi",
"version": "1.0.0"
}Projenin adını temsil eder ve tanımlanması zorunludur. Proje adını tanımlarken şunlara dikkat etmelisiniz:
- tümü küçük harf olmalıdır
- tek kelime olmalıdır
- tire, alt çizgi ve nokta içerebilir
- alt çizgi ya da nokta ile başlamamalıdır.
"name": "proje-adi.falan_filan"Projenin versiyonunu temsil eder ve tanımlanması zorunludur. Versiyonlamayı semantic versiyonlamaya uygun olarak belirlemelisiniz.
Yani 3 değerli bir versiyon olacak.
MAJOR.MINOR.PATCH şeklinde.
MAJOR- Bir önceki versiyon tamamen ya da kısmen değiştirildiyse ve mevcut yapı artık korunmuyorsa iseMINOR- Mevcut yapı korunarak yeni özellikler eklenmiş isePATCH- Mevcut yapı korunarak hatalar vs. düzeltilmiş ise.
"version": "1.0.0"Projenin ne olduğu, amacı genelde bu değerde belirtilir.
"description": "Bir amacı olmayan proje"Projenin çalışması için gerekli olan sürümler burada anahtar-değer şeklinde belirtilir. Örneğin projenizin çalışması için node'un belli bir sürümü gerekiyorsa bunu şöyle belirtebilirsiniz:
"engines": {
"node": "14.18.0"
}Projenin bağımlılıkları burada belirtilir. Yani projenin ihtiyaç duyduğu paketler. Yeni bir paket yüklediğinizde bu listeye otomatik eklenecektir.
"dependencies": {
"bcryptjs": "^2.4.3",
"cors": "^2.8.5",
"dotenv": "^6.1.0",
"express": "^4.16.4",
}Adındanda anlaşılacağı üzere, projenizin geliştirme ortamında ihtiyaç duyduğunuz ancak production ortamında ihtiyacınız olmayacak paketler.
"devDependencies": {
"eslint": "^4.19.1",
"mocha": "^6.2.0",
"nodemon": "^1.19.1",
}Çalıştırılmasını istediğiniz komutları burada anahtar-değer şeklinde belirtiyorsunuz. Örneğin node ile bir javascript dosyasını çalıştırmak için kullandığımız komutu script'lere ekleyebilirdik:
"scripts": {
"baslat": "node ./index.js"
}ve artık uzun uzun yazmak yerine şu şekilde çalıştırabilirdik:
npm run baslatProje ya da paketle ilgili anahtar kelimeleri belirliyoruz.
"keywords": ["node", "test", "learning"]Varsayılan olarak node kendi modül yapısı olan commonjs kullanıyor. Yani dayjs paketini yükleyip bunu kullanmak isteseydik şöyle kullanacaktık:
# paketi kur
npm i dayjspaketi js dosyamızda çağırıp basit bir kullanımını görelim.
// index.js
let dayjs = require('dayjs')
console.log('Bugünün tarihi', dayjs().format('YYYY-MM-DD'))Eğer type değerini module e çevirirsek, artık ES6 modül yapısını kullanabiliriz.
// index.js
import dayjs from 'dayjs'
console.log('Bugünün tarihi', dayjs().format('YYYY-MM-DD'))Bu modül yapısını daha detaylı inceleyeceğiz, merak etmeyin :)
JavaScript'in ES6 sürümü ile gelen ve react yazarkende sıkça kullanacağımız yenilikleri tek tek inceleyelim. React ile geliştirme yaparken bunlara hakim olmak sizi projenizi yazarken daha özgüvenli olmanızı sağlayacaktır.
Javascript'de bugüne kadar function anahtar kelimesiyle fonksiyon oluşturmuş olabilirsiniz. Ancak ES6 ile birlikte arrow fonksiyonları oluşturmak ve kullanmak çok daha kolay.
Normal bir fonksiyon şöyle oluşturuluyor:
function sayHi(name) {
return `Hi, ${name}`
}Bu fonksiyonunun aynısını arrow fonksiyonu ile oluşturmak isteseydik:
const sayHi = (name) => {
return `Hi, ${name}`
}Eğer tek bir parametre alıyorsanız () kullanmadan da yazabilirsiniz.
const sayHi = name => {
return `Hi, ${name}`
}Ve tek satıra bir return işlemi yapıyorsanız şöyle daha kısa olarak yazabilirdiniz:
const sayHi = name => `Hi, ${name}`ES6 ile birlikte standart haline gelmiş dil seviyesinde bir modül yapımız var. Temel olarak yaptığımız kodlarımızı ayırmak ve ihtiyaç halinde bunları çağırarak kullanmak.
export ile dosyalardan değişken, fonksiyon vs. dışa aktarabiliyoruz. Ve ihtiyaç halinde ilgili dosyayı import ederek export edilen değerlere ulaşıp kullanabiliyoruz.
Bir javascript dosyasından daha sonra kullanmak üzere hemen hemen her şeyi dışa aktarabiliriz. Örneğin bir değişken, bir fonksiyon, bir class vs.
Dışa aktarırken default olarak ya da obje olarak aktarım yapabiliriz. Elbette bu aktarım türüne göre çağırırken bazı farklılıklar olacak.
Örneğin verdiğimiz değeri tersine çevirip geri döndüren bir fonksiyonumuz olsun. Ve bunu varsayılan olarak dışarı aktarmayı görelim.
// utils.js
function getReverseText(text) {
return text.split('').reverse().join('')
}
export default getReverseTextŞimdi de dışa aktarılan fonksiyonu bir başka dosyada çağırıp kullanalım.
// app.js
import getReverseTextFunction from "./utils.js"
console.log(getReverseTextFunction('tayfun erbilen'))Ve bunu node yardımı ile çalıştırıp testimizi yapalım.
node ./app.jsSonuç olarak başarıyla terse çevrilmiş bir değer göreceğiz. Fark ettiğiniz üzere import ederken export edilen fonksiyonun adı yerine farklı bir isim kullandık. Çünkü varsayılan olarak dışa aktarılan değeri istediğimiz gibi isimlendirebiliriz.
Varsayılan olarak export işlemi haricinde farklı şeyleri de dışa aktarmak isteyebiliriz. Bunu yapmak için default değeri olmadan dışa aktarmak gerekir. Aynı dosyada birkaç şeyi daha dışarı aktaralım.
// utils.js
const API_URL = 'https://api.test.com/'
const secondsToTime = seconds => {
return new Date(seconds * 1000)
.toISOString()
.substr(11, 8)
}
function getReverseText(text) {
return text.split('').reverse().join('')
}
export default getReverseText
export {
API_URL,
secondsToTime
}Şimdi bu dışa aktardığımız şeyleri yine kullanmayı deneyelim.
// app.js
import getReverseTextFunction, { API_URL, secondsToTime } from "./utils.js"
console.log(getReverseTextFunction('tayfun erbilen'))
console.log(API_URL)
console.log(secondsToTime(360))Gördüğünüz gibi varsayılan olarak dışa aktarmıyorsak obje içinde dışa aktarılanları alıp kullanmamız gerekiyor. Ve isimlendirme dışa aktarılanla birebir aynı olmalı.
Ayrıca en altta export {} ile belirtmek yerine değişken ya da fonksiyonların başına koyarakta bu dışa aktarımı uygulayabilirdik.
// utils.js
export const API_URL = 'https://api.test.com/'
export const secondsToTime = seconds => {
return new Date(seconds * 1000)
.toISOString()
.substr(11, 8)
}
export default function getReverseText(text) {
return text.split('').reverse().join('')
}Değişken, fonksiyon ya da sınıfları dışa aktarırken farklı bir isimle kullanmak isterseniz as ile yeniden izimlendirip dışa aktarabilirsiniz.
// ...
export {
API_URL as BASE_URL,
secondsToTime as convertSeconds
}İçe aktarılan değişken, fonksiyon ya da sınıfları yeniden isimlendirmek içinde as değerini kullanabilirsiniz.
import getReverseText, { API_URL as BASE_URL, secondsToTime as convertSeconds } from "./utils.js";Tüm dışa aktarılanları tek bir isimde toplayıp kullanmak isterseniz import * değerinden sonra as ile isimlendirip kullanabilirsiniz.
import * as Utils from "./utils.js"
console.log(Utils)
console.log(Utils.API_URL)
console.log(Utils.default('tayfun erbilen'))Bazı durumlarda dosyayı direk import etmek yerine ihtiyaç anında import edip kullanmak isteyebilirsiniz. İşte bu gibi durumlarda import() metodunu kullanacağız.
Bu bize bir Promise dönecek. Henüz öğrenmediğimiz bir kavram ancak kullanımına bakalım, promise dersinde buraya dönüp tekrar incelersiniz kodu.
setTimeout(() => {
console.log('import ediliyor..')
import('./utils.js')
.then(utils => {
console.log(utils)
})
}, 2000)Ayrıca yine henüz öğrenmediğimiz async/await yapısı ile de şöyle yapabilirdik:
setTimeout(async () => {
console.log('import ediliyor..')
const utils = await import('./utils.js')
console.log(utils)
}, 2000)Bir metoda parametre olarak atanan fonksiyonlara callback fonksiyonları denir. Callback fonksiyonları aslında faydalıdır ancak bazı durumlar hariç.
Mesela şöyle bir senaryomuz olsun, bazı görevler başlatacağız, fakat başlanan görev bitmeden diğer göreve başlamasını istemiyoruz. Örneğin kod yapımız şöyle olabilirdi:
setTimeout(() => {
console.log('1. task')
setTimeout(() => {
console.log('2. task')
setTimeout(() => {
console.log('3. task')
setTimeout(() => {
console.log('4. task')
setTimeout(() => {
console.log('5. task')
setTimeout(() => {
console.log('6. task')
}, 1000)
}, 1000)
}, 1000)
}, 1000)
}, 1000)
}, 1000)işte tam bu noktada bu şekli alıyorsa kodlarımız callback hell dediğimiz illete yakalanıyor :D
Yani callback içinde callback içinde callback... Bu böyle gider, bunu daha düzenli yazmak için Promise kullanabilirdik.
Promise, ES6 ile gelen özelliklerden bir tanesi. Amaç ise, bir işlem başarılı ise yani resolve olmuşsa ya da başarısız ise yani reject olmuşsa ve her koşulda çalışabilecek kod blokları yazmak.
En basit haliyle bir promise yapısına bakacak olursak:
const promise = new Promise((resolve, reject) => {
if (true) {
resolve('başarılı')
} else {
reject('başarısız!')
}
})Yukarıdaki örnekte her türlü resolve() metodu çalışacak ancak önemli değil, mantığı anlamak için bakabiliriz.
Şimdi bu promise yapısında başarılı olanlar yani resolve edilenler then() bloğunda yakalanıyor.
Başarısız yani reject edilenler ise catch() bloğunda yakalanıyor.
Her iki durumda da bir kod bloğu çalıştırmak isterseniz de finally() bloğunu kullanabilirsiniz.
Buna göre yukarıdaki promise'i çalıştıralım.
promise.then(response => console.log(response))
.catch(error => console.log(error))
.finally(() => console.log('paşa gönlüme göre!'))Şimdi mesela basit bir örnek yapalım. Callback hell bölümünde bahsettiğimiz o cehennemden kurtulmak için promise kullanalım.
const wait = second => new Promise(resolve => setTimeout(resolve, second * 1000))
wait(1)
.then(() => {
console.log('1. task')
return wait(1)
})
.then(() => {
console.log('2. task')
return wait(1)
})
.then(() => {
console.log('3. task')
return wait(1)
})
.then(() => {
console.log('4. task')
return wait(1)
})Unutmayın,
then()ile return ettiğiniz işlemi bir sonraki then'de yine callback'te parametre olarak alabilirsiniz.
Javascript'de her şey senkron olarak işleniyor. Bazı durumlarda, asenkron işlemleri sıraya koymamız gerekebilir.
Yine yukarıdaki örneği düşündüğümüzde, API'mize bir istek attığımızda cevabın ne zaman döneceği belli olmadığı için, Promise yapısını kullanarak bunu çözüyoruz.
Ancak Promise de her zaman than() catch() ve finally() bloklarını kullanmak istemeyebiliriz. Bu gibi durumlarda, async/await kullanacağız.
Yukarıdaki örneğimizi async/await yapısına çevirelim.
const wait = second => new Promise(resolve => setTimeout(resolve, second * 1000))
async function runTasks() {
await wait(1)
console.log('1. task')
await wait(1)
console.log('2. task')
await wait(1)
console.log('3. task')
await wait(1)
console.log('4. task')
}
runTasks()Gördüğünüz gibi bir fonksiyon içinde bunu yapmamız gerekiyor. Çünkü fonksiyon'a async değerini atıyoruz.
Böylece fonksiyon içinde işlemin bitmesi gerektiğini await ile belirtiyoruz. Bu cevap dönene kadar altındaki kodlar çalışmıyor. Ne zmana cevap döndü, bir sonraki kod çalıştırılıyor ve tekrar bir bekleme varsa onu bekleyip yine işlem bu şekilde devam edip gidiyor.
spread operatörü adındanda belli olduğu üzere bir diziyi ya da objeyi yaymak için kullanılıyor.
rest operatörü de yine adındanda belli olduğu üzere kalanı temsil ediyor.
Her ikiside ...degisken şeklinde kullanılıyor. Kullanıldığı yere göre spread ya da rest işlemini görüyor.
Örneğin bir dizimiz olsun ve bu dizi elemanlarını fonksiyona göndererek console'a basalım.
const names = ['Tayfun', 'Mehmet', 'Ahmet']
function showNames(name1, name2, name3) {
console.log(name1)
console.log(name2)
console.log(name3)
}
showNames(names[0], names[1], names[2])Sonuç isimleri tek tek yazdıracaktır. Ancak fonksiyon'a böyle dizi elemanlarını tek tek belirtmek biraz sıkıntılı. Çünkü diziye yeni bir eleman geldiğinde bunu tekrar şöyle belirtmem gerekli.
showNames(names[0], names[1], names[2], names[3])Bunun yerine eğer diziyi yayıyor olsaydım o zaman şöyle yapmam yeterli olacaktı.
showNames(...names)Artık showNames() fonksiyonunda bir değişiklik yapmadan yine aynı sonucu aldım.
Peki, spread operatörünü gördük. Olay bundan ibaret, rest operatörü? O da fonksiyonda kullanacağız. Şöyle ki;
const names = ['Tayfun', 'Mehmet', 'Ahmet', 'Gökhan', 'Zerafet']
function showNames(name1, name2, name3, ...otherNames) {
console.log(name1)
console.log(name2)
console.log(name3)
console.log(otherNames)
}
showNames(...names)Ayrıca spread ile referanssız bir objede tanımlayabiliriz. Mesela bir user objemiz olsun, bir başka user'ı bu objeden türetip kullanmayı deneyelim.
const user = {
name: 'Tayfun',
surname: 'Erbilen'
}
const newUser = user
newUser.name = 'Recep'
console.log(user)
console.log(newUser)Gördüğünüz gibi her iki objede değişti, çünkü newUser referans olarak user ı baz alıyor. Dolayısı ile onda bir değişiklik yapınca asıl referans aldığımız objede değişiyor. Ama bunu spread ile yayıp şöyle kullansaydık her şey istediğimiz gibi olabilirdi.
const user = {
name: 'Tayfun',
surname: 'Erbilen'
}
const newUser = {
...user
}
newUser.name = 'Recep'
console.log(user)
console.log(newUser)Bir başka örnekte, react'de sıkça kullanacağımız servisleri yönetmekle alakalı olabilir. Düşünün ki istekleri yönettiğiniz request adında bir metodunuz olsun. Ve bu metod bazı varsayılan ayarlar alıyor olsun.
function request(url, opts = {}) {
const options = {
error: true,
success: true,
...opts
}
console.log(options)
}
request('/', {
success: false
})Ne yapmış olduk? Varsayılan ayarları, parametre'de göndererek ezmiş olduk. Böylece bu istekte başarılı olursa bir başarılı mesajı göstermek istemediğimi söyledim.
Başka bir örnekte dizileri birleştirmek olabilir. Örneğin;
const numbers = [0, 1, 2, 3]
console.log( [-2, -1, ...numbers, 4, 5] )Destructuring, dizi ve objelerde değerleri isimlendirerek kullanmamızı sağlıyor.
Örneğin şöyle bir dizimiz olsun:
const user = ['Tayfun', ' ', 'Erbilen']
console.log(user[0], user[1], user[2])bu şekilde kullanmak yerine daha anlamlı bir isimlendirme ile şöyle kullanabilirdik:
const user = ['Tayfun', ' ', 'Erbilen']
const [name, space, surname] = user
console.log(name, space, surname)Obje içinde bir örnek verecek olursak:
const user = {
name: 'Tayfun',
surname: 'Erbilen',
age: 29
}
console.log(user.name)
console.log(user.surname)
console.log(user.age)Yine böyle uzun uzun yazmak yerine isimlendirip şöyle kullanabilirdik:
const user = {
name: 'Tayfun',
surname: 'Erbilen',
age: 29
}
const { name, surname, age } = user
console.log(name)
console.log(surname)
console.log(age)Farkettiğiniz üzere dizilerde [] kullanırken objelerde {} kullanıyoruz.
Ayrıca dizilerde bir ismi olmadığı için istediğimiz isimle kullanırken, objelerde mevcut özellik adını yazmak zorundayız.
Diyelim ki yazmak istemiyoruz, o zaman yeniden isimlendirmeyi sonuna : koyarak yapabiliriz. Örneğin:
const user = {
name: 'Tayfun',
surname: 'Erbilen',
age: 29
}
const { name: ad, surname: soyad, age: yas } = user
console.log(ad)
console.log(soyad)
console.log(yas)Bu genelde, çalıştığınız bir API düzgün response dönemiyorsa bir standart haline getirmek için tercih edilebilir.
Ayrıca bu user objesini bir fonksiyona parametre olarak gönderseydik, fonksiyon içinde de isimlendirip kullanabilirdik. Şöyle ki:
const user = {
name: 'Tayfun',
surname: 'Erbilen',
age: 29
}
function showUser({ name, surname, age }) {
console.log(name, surname, age)
}
showUser(user)Ayrıca objemiz iç içe de obje içerebilirdi. Bu durumda onlarıda isimlendirerek kullanmak isteseydik şöyle bir örnek verebilirdik:
const user = {
name: 'Tayfun',
surname: 'Erbilen',
age: 29,
pets: {
dogs: ['Monti'],
cats: ['Paşa', 'Göbek']
}
}
function showUser({ name, surname, age, pets: { dogs: [ kopek1 ], cats: [ kedi1, kedi2 ] } }) {
console.log(kopek1)
}
showUser(user)Eğer değer yoksa varsayılan bir değerde belirtebilirdik: Örneğin:
const user = {
name: 'Tayfun',
//surname: 'Erbilen',
age: 29
}
function showUser({ name, surname = 'Soyad Yok!', age }) {
console.log(name, surname, age)
}
showUser(user)Parametre olarak fonksiyon olan metodlara yüksek mertebe fonksiyonlar diyebiliriz. Javascript'de diziler için bir takım yüksek mertebe fonksiyonlar var, bunlara da sırasıyla bakalım.
Bir ifadede aranan kelimenin geçip geçmediğini kontrol eder. Dizilerde ise eşleşen bir değer olup olmadığını kontrol eder.
Örneğin dizide 7 değeri var mı kontrol edelim.
const numbers = [1, 3, 5, 7]
console.log(numbers.includes(7))const numbers = [1, 3, 5, 7]
const addNumber = number => {
if (!numbers.includes(number)) {
numbers.push(number)
}
}
addNumber(5)
addNumber(5)
addNumber(6)
addNumber(7)
addNumber(8)
console.log(numbers)Ayrıca 2. parametreye kaçıncı index'ten aramaya başlayacağını belirtebilirdik.
const names = ['tayfun', 'gökhan', 'mehmet']
console.log(names.includes('tayfun', 1))Dizi öğelerini manipüle ederek yeni bir dizi oluşturmanızı sağlar.
Dizi içindeki sayıları 2 ile çarparak yeni bir dizi oluşturalım.
const numbers = [1, 3, 5, 7]
numbers.forEach((number, index) => numbers[index] = number * 2)
const multiplyNumbers = numbers.map(number => number * 2)
const multiplyNumbers = numbers.map(number => Math.sqrt(number))Dizi içindeki objeleri değiştirerek yeni bir dizi oluşturalım.
const users = [
{ name: 'Tayfun', surname: 'Erbilen', age: 29 },
{ name: 'Ahmet Tarık', surname: 'Günal', age: 25 },
]
const date = new Date()
const newUsers = users.map(user => ({
fullName: `${user.name} ${user.surname}`,
dateOfBirth: date.getFullYear() - user.age
}))
console.log(newUsers)Dizi içindeki todo item'larında sadece gönderdiğimiz id ile eşleşen todonun değerini değiştirelim.
let todos = [
{ id: 1, text: 'todo 1', completed: false },
{ id: 2, text: 'todo 2', completed: false },
{ id: 3, text: 'todo 3', completed: false },
]
function completeTodo(id) {
todos = todos.map(todo => {
if (todo.id === id) {
todo.completed = true
}
return todo
})
}
completeTodo(2)
console.log(todos)..
Dizi içindeki öğeleri belirli kriterlere göre filtrelemizi sağlar ve filtrelenmiş yeni bir dizi döndürür.
Örneğin 2'ye bölünebilen ve kalanı 0 olan sayıları filtreyelim.
const numbers = [1, 3, 4, 5, 7, 8, 10]
console.log(
numbers.filter(number => number % 2 === 0)
)İsim uzunluğu 4 ve daha küçük olanları filtreyelim.
const names = ['tayfun', 'cem', 'ece', 'burak', 'gül', 'mehmet', 'neşe']
console.log(
names.filter(name => name.length <= 4)
)Yaşı sadece 29 olanları filtreyelim.
const users = [
{ name: 'Tayfun', age: 29 },
{ name: 'Mehmet', age: 29 },
{ name: 'Ahmet', age: 24 },
{ name: 'Gökhan', age: 32 },
]
console.log(
users.filter(user => user.age === 29)
)İsimler içinde aradığımız değer geçenleri filtreleyelim.
const names = ['tayfun', 'cem', 'ece', 'burak', 'gül', 'mehmet', 'neşe']
console.log(
names.filter(name => name.includes('ce'))
)
const search = (keyword, array) => array.filter(item => item.toLocaleLowerCase('TR').includes(keyword.toLocaleLowerCase('TR')))
console.log(
search('cE', names)
)Dizi öğelerini azaltarak tek bir değer haline getirmemizi sağlar.
Sayılardan oluşan bir dizimiz olsun, bunların toplamını bir değişkene yazdırmak istesek ne yapardık?
const numbers = [1, 3, 5, 7]
let total = 0
numbers.forEach(number => total += number)
console.log('Toplam', total)Bunun aynısını reduce ile yapmak isteseydik:
let total = numbers.reduce((acc, number) => acc += number, 0)
console.log(total)Düşününki bir alışveriş sepetiniz var, sepetin toplam tutarını yazdırmak istiyorsunuz? Hadi gelin deneyelim.
const basket = [
{
name: 'Ürün 1',
price: 1200
},
{
name: 'Ürün 2',
price: 1500
},
{
name: 'Ürün 3',
price: '15.00'
},
]Dizideki isimlerin kaç kere tekrarlandığını bulalım.
const names = ['tayfun', 'mehmet', 'ahmet', 'gökhan', 'tayfun']
const result = names.reduce((allNames, name) => {
if (name in allNames) {
allNames[name]++
} else {
allNames[name] = 1
}
return allNames
}, {})
console.log(result)Belirli bir key'e göre gruplama yapalım.
const users = [
{
name: "Tayfun",
role: 'admin'
},
{
name: 'Mehmet',
role: 'user'
},
{
name: 'Gökhan',
role: 'super-admin'
},
{
name: 'Ahmet',
role: 'user'
}
]
let group = 'role'
const groupedUsers = users.reduce((acc, user) => {
let key = user[group]
if ( !acc[key] ) {
acc[key] = []
}
acc[key].push({name: user.name})
return acc
}, {})
console.log(groupedUsers)Post'larda etiketlerin tamamını alıp tekilleştirelim.
const posts = [
{ name: 'Post1', tags: ['html', 'css'] },
{ name: 'Post2', tags: ['css', 'php'] },
{ name: 'Post3', tags: ['react', 'js'] },
{ name: 'Post4', tags: ['react', 'js'] },
]
const allTags = posts.reduce((acc, post) => [...acc.filter, ...post.tags], [])
for (let value of new Set(allTags).values()) {
console.log(value)
}filter ve map yerine reduce kullanmak isteseydik:
const numbers = [-5, 6, 2, 0]
console.log(
numbers.filter(number => number > 0).map(number => number * 2)
)
console.log(
numbers.reduce((acc, number) => {
if (number > 0) {
acc.push(number * 2)
}
return acc
}, [])
)Eşleşen ilk değeri döndürür.
Örneğin 10'dan büyük ilk değeri bulalım.
const numbers = [5, 12, 6, 120, 44]
console.log(
numbers.find(number => number > 10)
)ya da id'si 2 olan üyeyi bulalım.
const users = [
{id: 1, name: 'Tayfun'},
{id: 2, name: 'Mehmet'},
{id: 3, name: 'Gökhan'},
]
const user = users.find(user => user.id === 2)
console.log(user)find metodunun aynısı, sadece öğe yerine index değerini geriye döndürüyor.
Değerleri test etmek için kullanıyoruz.
every ile her bir değerin koşulumuza uyup uymadığını kontrol ediyoruz, uyuyorsa true uymuyorsa false döndürüyor.
const numbers = [2, 4, 6, 8, 10]
console.log(
numbers.every(number => number % 2 === 0)
)some ise koşul en az 1'inde geçerliyse true değilse false döndürüyor.