Mengedit State Parent di Child Component di React
Sekarang mari kita edit produk kita menggunakan input. Untuk melakukan ini, di child component buatlah sebuah tombol.
Saat pertama kali tombol ini ditekan, biarkan alih-alih nama dan harga produk, muncul input untuk mengeditnya, dan saat ditekan kedua kalinya alih-alih input, muncul kembali teks.
Mari kita ubah array produk, menambahkan
properti isEdit (dan untuk mempermudah, kerja dengan keranjang belanja
kita hilangkan):
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},
];
Komponen Product
Mari buat tombol untuk mengedit di dalam produk:
function Product({ id, name, cost, isEdit }) {
return <div>
name: <span>{name}</span>
cost: <span>{cost}</span>
<button>edit</button>
</div>;
}
Mari kita atur sehingga ketika tombol ini diklik,
sebuah fungsi toggleMode akan dipanggil,
yang diteruskan dari komponen induk:
function Product({ id, name, cost, isEdit, toggleMode }) {
return <div>
name: <span>{name}</span>
cost: <span>{cost}</span>
<button onClick={() => toggleMode(id)}>
edit
</button>
</div>;
}
Kita belum memiliki implementasi toggleMode,
tapi kita tahu bahwa fungsi itu akan berada
di komponen induk, menerima parameter
id produk dan mengubah properti isEdit
produk menjadi kebalikannya.
Mari kita juga atur agar teks tombol berubah setiap kali ditekan:
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>;
}
Sekarang mari kita buat agar dalam mode editing, kita memiliki input dengan data, dan dalam mode biasa - kita memiliki elemen span:
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>;
}
Mari kita tambahkan event onChange ke input kita,
di dalamnya kita akan memanggil suatu fungsi induk
editProd:
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>;
}
Komponen Products
Sekarang mari kita beralih ke komponen Products.
Mari kita implementasikan fungsi toggleMode di dalamnya:
function toggleMode(id) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod.isEdit = !prod.isEdit;
}
return prod;
}));
}
Juga, mari kita implementasikan fungsi editProd di dalamnya:
function editProd(id, field, event) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod[field] = event.target.value;
}
return prod;
}));
}
Di dalam tag produk, kita akan oper fungsi-fungsi kita
toggleMode dan editProd sebagai atribut:
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}
/>;
});
Kode akhir komponen Products
akan menjadi seperti berikut:
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>;
}
Tugas Praktis
Lakukan operasi serupa dengan komponen
Users dan User, yang telah Anda buat
pada pelajaran sebelumnya.