Mengubah State Parent di Child Component di React
Dalam pelajaran sebelumnya, state dengan data disimpan di komponen parent, dan komponen child menerima data tersebut dalam bentuk props.
Sekarang misalkan kita ingin mengubah produk kita.
Mari kita buat, contohnya, sebuah tombol yang akan
menempatkan produk kita ke dalam keranjang. Untuk memulai
mari kita tambahkan ke array produk kita
bidang inCart, yang menunjukkan apakah produk
berada di keranjang atau tidak:
const initProds = [
{id: id(), name: 'product1', cost: 100, inCart: false},
{id: id(), name: 'product2', cost: 200, inCart: false},
{id: id(), name: 'product3', cost: 300, inCart: false},
];
Di dalam komponen Products, di tag dengan produk
tambahkan atribut lain inCart:
function Products() {
const [prods, setProds] = useState(initProds);
const items = prods.map(prod => {
return <Product
key ={prod.id}
name ={prod.name}
cost ={prod.cost}
inCart={prod.inCart}
/>;
});
return <div>
{items}
</div>;
}
Mari kita di komponen child Product
buat tampilan informasi tentang keranjang dan tombol
untuk menambahkan ke keranjang:
function Product({ id, name, cost, inCart }) {
return <div>
name: <span>{name}</span>,
cost: <span>{cost}</span>,
<span>{inCart ? 'in cart' : 'not in cart'}</span>
<button>to cart</button>
</div>;
}
Implementasikan Penambahan
Menurut aturan React, sebuah komponen tidak boleh
mengubah props-nya sendiri. Ini berarti bahwa
komponen child tidak dapat menempatkan dirinya sendiri
ke dalam keranjang dengan mengubah prop inCart.
Itu tidak benar.
Cara yang benar adalah meminta komponen parent
untuk mengubah state prods-nya, dengan menempatkan
produk tertentu ke dalam keranjang.
Mari kita lihat, bagaimana hal ini dilakukan.
Di komponen parent, buat fungsi addToCart,
yang menerima parameter id produk
dan untuk produk tersebut mengubah properti inCart
menjadi true:
function addToCart(id) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod.inCart = true;
}
return prod;
}));
}
Di tag dengan produk tambahkan atribut, di mana
kita meneruskan fungsi yang telah kita buat, serta
atribut, di mana kita meneruskan id produk:
const items = prods.map(prod => {
return <Product
key ={prod.id}
id ={prod.id}
name ={prod.name}
cost ={prod.cost}
inCart ={prod.inCart}
addToCart={addToCart}
/>;
});
Seperti yang Anda lihat, di dalam props komponen Anda bisa meneruskan tidak hanya beberapa data, tetapi juga fungsi.
Kode akhir dari kelas Products akan
menjadi seperti berikut:
function Products() {
const [prods, setProds] = useState(initProds);
function addToCart(id) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod.inCart = true;
}
return prod;
}));
}
const items = prods.map(prod => {
return <Product
key ={prod.id}
id ={prod.id}
name ={prod.name}
cost ={prod.cost}
inCart ={prod.inCart}
addToCart={addToCart}
/>;
});
return <div>
{items}
</div>;
}
Sekarang di kelas child kita akan memiliki akses ke
fungsi addToCart. Panggil fungsi ini
pada klik tombol, dengan meneruskan parameter
id produk kepadanya:
function Product({ id, name, cost, inCart, addToCart }) {
return <div>
name: <span>{name}</span>,
cost: <span>{cost}</span>,
<span>{inCart ? 'in cart' : 'not in cart'}</span>
<button onClick={() => addToCart(id)}>to cart</button>
</div>;
}
Hasilnya adalah, ketika tombol di child diklik, fungsi dari parent akan terpanggil, yang kemudian akan mengubah state parent. Perubahan state parent akan memicu render ulang dan menggambar ulang produk kita, dengan meneruskan prop yang telah diubah.
Ambil komponen User dari pelajaran
sebelumnya. Buatlah agar di dalamnya muncul
tombol untuk mem-ban user.