Etkileşim Ekleme
Ekrandaki bazı şeyler kullanıcı girdisine yanıt olarak güncellenir. Örneğin, bir resim galerisine tıklamak aktif resmi değiştirir. React’te, zaman içinde değişen verilere state denir. Herhangi bir bileşene state ekleyebilir ve gerektiğinde güncelleyebilirsiniz. Bu bölümde, etkileşimleri işleyen, durumlarını güncelleyen ve zaman içinde farklı çıktılar görüntüleyen bileşenleri nasıl yazacağınızı öğreneceksiniz.
Bu bölümde
- Kullanıcı tarafından başlatılan olaylar nasıl ele alınır
- State kullanılarak bileşenlerin bilgiyi “hatırlaması” nasıl sağlanır
- React kullanıcı arayüzünü iki aşamada nasıl günceller
- State neden onu değiştirdiğiniz anda güncellenmez
- Birden çok state güncellemesi sıraya nasıl alınır
- State içerisindeki nesne nasıl güncellenir
- State içerisindeki dizi nasıl güncellenir
Olaylara tepki verme
React, JSX’inize olay yöneticileri eklemenize olanak tanır. Olay yöneticileri; tıklama, üzerine gelme (hover), form girdilerine odaklanma gibi kullanıcı aksiyonlarına tepki vermek için tetiklenecek olan fonksiyonlarınızdır.
<button>
gibi yerleşik bileşenler yalnızca onClick
gibi yerleşik tarayıcı olaylarını destekler. Ancak kendi bileşenlerinizi oluşturabilir ve olay yöneticisini ileteceğiniz prop’lara uygulamanıza özgü isimler verebilirsiniz.
export default function App() { return ( <Toolbar onPlayMovie={() => alert('Oynatılıyor!')} onUploadImage={() => alert('Yükleniyor!')} /> ); } function Toolbar({ onPlayMovie, onUploadImage }) { return ( <div> <Button onClick={onPlayMovie}> Filmi Oynat </Button> <Button onClick={onUploadImage}> Resim Yükle </Button> </div> ); } function Button({ onClick, children }) { return ( <button onClick={onClick}> {children} </button> ); }
Bu konuyu öğrenmeye hazır mısınız?
Olay yöneticilerinin nasıl ekleneceğini öğrenmek için Olaylara Tepki Verme bölümünü okuyun.
Devamını OkuState: bir bileşenin hafızası
Bileşenlerin, genellikle bir etkileşim sonucunda ekrandakileri değiştirmesi gerekir. Forma yazı yazmak girdi alanını güncellemeli, bir resim slaytında “ileri” tıklamak hangi resmin görüntüleneceğini değiştirmeli, “satın al” a tıklamak bir ürünü alışveriş sepetine koymalıdır. Bileşenlerin; mevcut girdi değeri, seçili görsel, alışveriş sepeti gibi şeyleri “hatırlaması” gerekir. React’te bu tür bileşene özgü bellekler state olarak adlandırılır.
useState
Hook’u ile bir bileşene state ekleyebilirsiniz. Hook’lar, bileşenlerinizde React özelliklerini kullanmanızı sağlayan özel fonksiyonlardır (state bu özelliklerden biridir). useState
Hook’u, bir state değişkeni bildirmenizi sağlar. Bu Hook başlangıç state’ini alır ve bir çift değer döndürür: mevcut state ve state’i güncellemenizi sağlayan bir fonksiyon.
const [index, setIndex] = useState(0);
const [showMore, setShowMore] = useState(false);
Aşağıda resim galerisinin state’i nasıl kullandığını ve state’i tıklama ile nasıl güncellendiğini görebilirsiniz:
import { useState } from 'react'; import { sculptureList } from './data.js'; export default function Gallery() { const [index, setIndex] = useState(0); const [showMore, setShowMore] = useState(false); const hasNext = index < sculptureList.length - 1; function handleNextClick() { if (hasNext) { setIndex(index + 1); } else { setIndex(0); } } function handleMoreClick() { setShowMore(!showMore); } let sculpture = sculptureList[index]; return ( <> <button onClick={handleNextClick}> Sonraki </button> <h2> {sculpture.artist}'den <i>{sculpture.name} </i> </h2> <h3> ({index + 1}/{sculptureList.length}) </h3> <button onClick={handleMoreClick}> Detayları {showMore ? 'Sakla' : 'Göster'} </button> {showMore && <p>{sculpture.description}</p>} <img src={sculpture.url} alt={sculpture.alt} /> </> ); }
Bu konuyu öğrenmeye hazır mısınız?
State: Bir Bileşenin Hafızası sayfasını okuyarak bir değeri nasıl hatırlayacağınızı ve etkileşim ile o değeri nasıl güncelleyeceğinizi öğrenin.
Devamını OkuRender et ve işle
Bileşenleriniz ekranda gösterilmeden önce, React tarafından render edilmek zorundadırlar. Bu işlemdeki adımları anlamak, kodunuzun nasıl çalıştığını düşünmenize ve davranışını açıklamanıza yardımcı olacaktır.
Bileşenlerinizin mutfakta malzemelerden lezzetli yemekler hazırlayan aşçılar olduğunu hayal edin. Bu senaryoda React, müşterilerin siparişlerini alan ve bu siparişleri sunan garsondur. Kullanıcı arayüzünü isteme ve sunma sürecinin üç aşaması vardır:
- Bir render tetiklemek (müşterinin siparişinin mutfaktaki aşçıya iletilmesi)
- Bileşeni render etmek (siparişin mutfakta hazırlanması)
- DOM’a işlemek (siparişin masaya götürülmesi)
Rachel Lee Nabors tarafından görselleştirilmiştir.
Bu konuyu öğrenmeye hazır mısınız?
Render et ve İşle sayfasını okuyarak kullanıcı arayüzü güncellemesinin yaşam döngüsünü öğrenin.
Devamını OkuAnlık görüntü olarak state
Sıradan JavaScript değişkenlerinin yanı sıra, React state’i daha çok anlık bir görüntü olarak davranır. Bu değişkeni ayarlamak zaten mevcut state değişkenini değiştirmez onun yerine yeniden render tetikler. Bu ilk başta şaşırtıcı gelebilir!
console.log(count); // 0
setCount(count + 1); // 1 ile yeniden render iste
console.log(count); // Hala 0!
Bu davranış, ince hatalardan kaçınmanıza yardımcı olur. Aşağıda küçük bir mesajlaşma uygulaması vardır. “Gönder” butonuna tıkladıktan sonra alıcıyı Bob ile değiştirin ve ne olacağını tahmin etmeye çalışın. 5 saniye sonra kimin ismi alert
kutusunda çıkacaktır?
import { useState } from 'react'; export default function Form() { const [to, setTo] = useState('Alice'); const [message, setMessage] = useState('Merhaba'); function handleSubmit(e) { e.preventDefault(); setTimeout(() => { alert(`${to}'a ${message} dediniz`); }, 5000); } return ( <form onSubmit={handleSubmit}> <label> Alıcı:{' '} <select value={to} onChange={e => setTo(e.target.value)}> <option value="Alice">Alice</option> <option value="Bob">Bob</option> </select> </label> <textarea placeholder="Mesaj" value={message} onChange={e => setMessage(e.target.value)} /> <button type="submit">Gönder</button> </form> ); }
Bu konuyu öğrenmeye hazır mısınız?
Anlık Görüntü Olarak State sayfasını okuyarak olay yönetecilerinde state’in neden “sabit” ve değişmez göründüğünü öğrenin.
Devamını OkuState güncellemelerinin kuyruğa alınması
Bu bileşen hatalıdır: “+3” butonuna tıklamak skoru sadece bir artırmaktadır.
import { useState } from 'react'; export default function Counter() { const [score, setScore] = useState(0); function increment() { setScore(score + 1); } return ( <> <button onClick={() => increment()}>+1</button> <button onClick={() => { increment(); increment(); increment(); }}>+3</button> <h1>Skor: {score}</h1> </> ) }
Anlık Görüntü Olarak State sayfası bu duruma neyin neden olduğunu açıklamaktadır. State’i değiştirmek yeni bir yeniden render isteyecektir ama hali hazırda çalışan koddaki state’i değiştirmeyecektir. Yani score
değeri setScore(score + 1)
çağırıldıktan hemen sonra 0
olmaya devam edecektir.
console.log(score); // 0
setScore(score + 1); // setScore(0 + 1);
console.log(score); // 0
setScore(score + 1); // setScore(0 + 1);
console.log(score); // 0
setScore(score + 1); // setScore(0 + 1);
console.log(score); // 0
Bu sorunu, state’i değiştirirken güncelleyici fonksiyon ileterek düzeltebilirsiniz. setScore(score + 1)
yerine setScore(s => s + 1)
kullanmanın “+3” butonunu nasıl düzelttiğine dikkat edin. Bu, birden çok state güncellemesini kuyruğa almanızı sağlar.
import { useState } from 'react'; export default function Counter() { const [score, setScore] = useState(0); function increment() { setScore(s => s + 1); } return ( <> <button onClick={() => increment()}>+1</button> <button onClick={() => { increment(); increment(); increment(); }}>+3</button> <h1>Skor: {score}</h1> </> ) }
Bu konuyu öğrenmeye hazır mısınız?
State Güncellemelerinin Kuyruğa Alınması sayfasını okuyarak state güncellemelerini nasıl kuyruğa alacağınızı öğrenin.
Devamını OkuState içerisindeki nesneleri güncelleme
State, nesneler de dahil olmak üzere herhangi bir JavaScript değerini tutabilir. Ancak, React state’inde tuttuğunuz nesneleri ve dizileri direkt olarak değiştirmemelisiniz. Onun yerine, nesneleri ve dizileri güncellemek istediğinizde, yeni bir tane yaratmanız gerekmektedir (ya da mevcut olanın kopyasını alın) ve daha sonra state’i o kopyayı kullanacak şekilde güncelleyin.
Genel olarak, değiştirmek istediğiniz nesneleri ve dizileri kopyalamak için ...
spread sözdimini kullanacaksınız. Örneğin, iç içe nesneleri güncellemek şöyle gözükecektir:
import { useState } from 'react'; export default function Form() { const [person, setPerson] = useState({ name: 'Niki de Saint Phalle', artwork: { title: 'Blue Nana', city: 'Hamburg', image: 'https://i.imgur.com/Sd1AgUOm.jpg', } }); function handleNameChange(e) { setPerson({ ...person, name: e.target.value }); } function handleTitleChange(e) { setPerson({ ...person, artwork: { ...person.artwork, title: e.target.value } }); } function handleCityChange(e) { setPerson({ ...person, artwork: { ...person.artwork, city: e.target.value } }); } function handleImageChange(e) { setPerson({ ...person, artwork: { ...person.artwork, image: e.target.value } }); } return ( <> <label> İsim: <input value={person.name} onChange={handleNameChange} /> </label> <label> Başlık: <input value={person.artwork.title} onChange={handleTitleChange} /> </label> <label> Şehir: <input value={person.artwork.city} onChange={handleCityChange} /> </label> <label> Resim: <input value={person.artwork.image} onChange={handleImageChange} /> </label> <p> <i>{person.artwork.title}</i> ({person.artwork.city} şehrinde yaşayan) {person.name} {' tarafından '} <br /> </p> <img src={person.artwork.image} alt={person.artwork.title} /> </> ); }
Eğer objeleri kopyalamak zor bir hale geldiyse, tekrarlı hale gelen kodu azaltmak için Immer gibi bir kütüphane kullanabilirsiniz:
{ "dependencies": { "immer": "1.7.3", "react": "latest", "react-dom": "latest", "react-scripts": "latest", "use-immer": "0.5.1" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test --env=jsdom", "eject": "react-scripts eject" }, "devDependencies": {} }
Bu konuyu öğrenmeye hazır mısınız?
State İçerisindeki Nesneleri Güncelleme sayfasını okuyarak nesneleri nasıl doğru şekilde güncellemeniz gerektiğini öğrenin.
Devamını OkuState içerisindeki dizileri güncelleme
State içerisinde saklayabileceğiniz bir diğer değiştirilebilir JavaScript nesnesi dizilerdir ve dizilere salt okunur olarak davranılmalıdır. Nesnelerde olduğu gibi, state’te saklı diziyi güncellemek istediğinizde, yeni bir tane yaratmanız gerekmektedir (ya da mevcut olanın bir kopyasını alın) ve daha sonra yeni diziyi kullanacak şekilde state’i ayarlayın:
import { useState } from 'react'; const initialList = [ { id: 0, title: 'Big Bellies', seen: false }, { id: 1, title: 'Lunar Landscape', seen: false }, { id: 2, title: 'Terracotta Army', seen: true }, ]; export default function BucketList() { const [list, setList] = useState( initialList ); function handleToggle(artworkId, nextSeen) { setList(list.map(artwork => { if (artwork.id === artworkId) { return { ...artwork, seen: nextSeen }; } else { return artwork; } })); } return ( <> <h1>Görülecek Sanat Eserleri Listesi</h1> <h2>Görmek istediğim eserler listesi:</h2> <ItemList artworks={list} onToggle={handleToggle} /> </> ); } function ItemList({ artworks, onToggle }) { return ( <ul> {artworks.map(artwork => ( <li key={artwork.id}> <label> <input type="checkbox" checked={artwork.seen} onChange={e => { onToggle( artwork.id, e.target.checked ); }} /> {artwork.title} </label> </li> ))} </ul> ); }
Eğer dizileri kopyalamak zor bir hale geldiyse, tekrarlı hale gelen kodu azaltmak için Immer gibi bir kütüphane kullanabilirsiniz:
{ "dependencies": { "immer": "1.7.3", "react": "latest", "react-dom": "latest", "react-scripts": "latest", "use-immer": "0.5.1" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test --env=jsdom", "eject": "react-scripts eject" }, "devDependencies": {} }
Bu konuyu öğrenmeye hazır mısınız?
State İçerisindeki Dizileri Güncelleme sayfasını okuyarak dizileri nasıl doğru şekilde güncellemeniz gerektiğini öğrenin.
Devamını OkuSırada ne var?
Olaylara Tepki Verme sayfasına gidin ve bu bölümü sayfa sayfa okumaya başlayın!
Bu konulara zaten aşina iseniz, neden State’i Yönetme sayfasını okumuyorsunuz?