React'ta Alt Bileşen State'leri ile Çalışma Modları
Ürün dizimizin artık şu şekilde göründüğünü varsayalım:
const initProds = [
{id: id(), name: 'prod1', cost: 'cost1', catg: 'catg1'},
{id: id(), name: 'prod2', cost: 'cost2', catg: 'catg2'},
{id: id(), name: 'prod3', cost: 'cost3', catg: 'catg3'},
];
Bu ürünleri bir HTML tablosu şeklinde gösterelim.
Ayrıca, tablodaki herhangi bir hücreye tıklandığında
o hücrede düzenleme için bir input kutusunun
belirmesini sağlayalım. Sorunu çözmek için
3 bileşen yapalım.
Products bileşeni, ürünlerle ilgili state'i
tutacak ve ürünleri göstermek için Product
bileşenlerini kullanacak. Product bileşeni de
sırasıyla, belirli bir ürün alanını (isim, fiyat, kategori)
göstermek için ProductField bileşenlerini
kullanacak.
ProductField bileşeni, ya alanın metnini
gösterecek ya da düzenleme için bir input kutusu
gösterecek. Bu durumda düzenleme veya gösterme modu
bu bileşenin state'i tarafından düzenlensin.
Yani modu üst state'te tutmayacağız. Burada bu çok elverişsiz olurdu, çünkü her ürün alanı için modu belirtmemiz gerekirdi, bu da state'imizi şunun gibi bir şeye dönüştürürdü:
const initProds = [
[
{field: 'name', value: 'prod1', isEdit: false},
{field: 'cost', value: 'cost1', isEdit: false},
{field: 'catg', value: 'catg1', isEdit: false},
],
[
{field: 'name', value: 'prod2', isEdit: false},
{field: 'cost', value: 'cost2', isEdit: false},
{field: 'catg', value: 'catg2', isEdit: false},
],
[
{field: 'name', value: 'prod3', isEdit: false},
{field: 'cost', value: 'cost3', isEdit: false},
{field: 'catg', value: 'catg3', isEdit: false},
],
]
Ancak, biz böyle bir state yapmayacağız ve
olanı olduğu gibi bırakacağız. Sadece her
ProductField bileşen örneği, kendi
state'ini kullanarak modu düzenleyecek:
ya düzenleme ya da gösterme.
Böylece, üst bileşen verilerle ilgili state'i tutarken, torun bileşenimiz bu verileri prop'lar aracılığıyla alacak ve aynı zamanda kendi modunu değiştirmek için kendi state'ine sahip olacak.
Peki, şimdi anlatılanları uygulayalım.
Products Bileşeni
function Products() {
const [prods, setProds] = useState(initProds);
function changeField(id, field, event) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod[field] = event.target.value;
}
return prod;
}));
}
const rows = prods.map(prod => {
return <Product
key ={prod.id}
id ={prod.id}
name={prod.name}
cost={prod.cost}
catg={prod.catg}
changeField={changeField}
/>;
});
return <div>
<table>
<tbody>
{rows}
</tbody>
</table>
</div>;
}
Product Bileşeni
function Product({ id, name, cost, catg, changeField }) {
return <tr>
<ProductField id={id} text={name} type="name" changeField={changeField} />
<ProductField id={id} text={cost} type="cost" changeField={changeField} />
<ProductField id={id} text={catg} type="catg" changeField={changeField} />
</tr>;
}
ProductField Bileşeni
function ProductField({ id, text, type, changeField }) {
const [isEdit, setIsEdit] = useState(false);
return <td>
{
isEdit
? <input
value={text}
onChange={event => changeField(id, type, event)}
onBlur={() => setIsEdit(false)}
/>
: <span onClick={() => setIsEdit(true)}>{text}</span>
}
</td>;
}
Pratik Görevler
Önceki derslerde oluşturduğunuz Users
ve User bileşenleriyle benzer işlemleri
gerçekleştirin.