React'ta Üst Bileşenin State'ini Alt Bileşende Düzenleme
Şimdi ürünlerimizi input'lar kullanarak düzenleyelim. Bunun için alt bileşende bir buton yapalım.
Bu butona ilk tıklandığında, ürünün adı ve fiyatı yerine bunları düzenlemek için input'lar görünsün, ikinci tıklamada ise input'lar yerine tekrar metinler görünsün.
Ürünler dizisinde, isEdit özelliğini ekleyerek
bir değişiklik yapalım
(ve basitlik için sepet işlevini kaldıralım):
const initProds = [
{id: id(), name: 'product1', cost: 100, isEdit: false},
{id: id(), name: 'product2', cost: 200, isEdit: false},
{id: id(), name: 'product3', cost: 300, isEdit: false},
];
Product Bileşeni
Ürün için düzenleme butonu yapalım:
function Product({ id, name, cost, isEdit }) {
return <div>
name: <span>{name}</span>
cost: <span>{cost}</span>
<button>edit</button>
</div>;
}
Bu butona tıklandığında, üst bileşenden iletilen
toggleMode adlı bir fonksiyonun çağrılmasını sağlayalım:
function Product({ id, name, cost, isEdit, toggleMode }) {
return <div>
name: <span>{name}</span>
cost: <span>{cost}</span>
<button onClick={() => toggleMode(id)}>
edit
</button>
</div>;
}
Henüz toggleMode uygulamamız yok,
ancak onun üst bileşende bulunacağını,
bir parametre olarak ürünün id' sini alacağını
ve ürünün isEdit özelliğini tersine çevireceğini biliyoruz.
Ayrıca, butonun metninin her tıklamada değişmesini sağlayalım:
function Product({ id, name, cost, isEdit, toggleMode }) {
return <div>
name: <span>{name}</span>
cost: <span>{cost}</span>
<button onClick={() => toggleMode(id)}>
{isEdit ? 'save': 'edit'}
</button>
</div>;
}
Şimdi, düzenleme modunda input'ların ve normal modda span'ların görünmesini sağlayalım:
function Product({ id, name, cost, isEdit, toggleMode }) {
return <div>
name: {isEdit ? <input value={name} /> : <span>{name}</span>}
cost: {isEdit ? <input value={cost} /> : <span>{cost}</span>}
<button onClick={() => toggleMode(id)}>
{isEdit ? 'save': 'edit'}
</button>
</div>;
}
Input'larımıza, içinde bir üst bileşen fonksiyonu olan
editProd'yu çağıracağımız bir onChange olayı bağlayalım:
function Product({ id, name, cost, isEdit, toggleMode, editProd }) {
return <div>
name: {
isEdit
? <input value={name} onChange={event => editProd(id, 'name', event)} />
: <span>{ name }</span>
}
cost: {
isEdit
? <input value={cost} onChange={event => editProd(id, 'cost', event)} />
: <span>{ cost }</span>
}
<button onClick={() => toggleMode(id)}>
{isEdit ? 'save': 'edit'}
</button>
</div>;
}
Products Bileşeni
Şimdi Products bileşenine geçelim.
İçinde toggleMode fonksiyonunu uygulayalım:
function toggleMode(id) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod.isEdit = !prod.isEdit;
}
return prod;
}));
}
Ayrıca içinde editProd fonksiyonunu uygulayalım:
function editProd(id, field, event) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod[field] = event.target.value;
}
return prod;
}));
}
Ürün etiketine, toggleMode ve editProd
fonksiyonlarımızı özellik olarak iletilim:
const items = prods.map(prod => {
return <Product
key ={prod.id}
id ={prod.id}
name={prod.name}
cost={prod.cost}
isEdit={prod.isEdit}
toggleMode={toggleMode}
editProd={editProd}
/>;
});
Products bileşeninin son kodu şu şekilde olacaktır:
function Products() {
const [prods, setProds] = useState(initProds);
function toggleMode(id) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod.isEdit = !prod.isEdit;
}
return prod;
}));
}
function editProd(id, field, event) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod[field] = event.target.value;
}
return prod;
}));
}
const result = prods.map(prod => {
return <Product
key ={prod.id}
id ={prod.id}
name={prod.name}
cost={prod.cost}
isEdit={prod.isEdit}
toggleMode={toggleMode}
editProd={editProd}
/>;
});
return <div>
{result}
</div>;
}
Pratik Görevler
Önceki derslerde oluşturduğunuz
Users ve User bileşenleriyle
benzer işlemleri gerçekleştirin.