Mod Pekerjaan Melalui State Komponen Anak dalam React
Katakanlah array produk kita kini kelihatan seperti berikut:
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'},
];
Mari kita paparkan produk-produk ini dalam bentuk jadual
HTML. Pada masa yang sama, kita akan buat supaya apabila
mana-mana sel jadual ditekan, input untuk pengeditan
akan muncul dalam sel tersebut. Untuk menyelesaikan masalah
ini, kita akan buat 3 komponen.
Komponen Products akan menyimpan state
dengan produk dan menggunakan komponen Product
untuk memaparkan produk. Komponen Product
sebaliknya juga akan menggunakan komponen
ProductField untuk memaparkan medan
produk tertentu (nama, harga, kategori).
Komponen ProductField akan sama ada
menunjukkan teks medan, atau input untuk
mengeditnya. Dalam keadaan ini, mod pengeditan
atau paparan biarlah diatur oleh state
komponen ini sendiri.
Maksudnya kita tidak akan menyimpan mod dalam state induk. Di sana ia akan menjadi sangat tidak selesa, kerana kita terpaksa menentukan mod untuk setiap medan produk, yang akan mengubah state kita menjadi sesuatu seperti ini:
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},
],
]
Walau bagaimanapun, kita tidak akan membuat state sedemikian,
sebaliknya kekalkan yang asal. Hanya setiap
instance komponen ProductField
menggunakan state sendiri akan mengatur
mod: sama ada pengeditan atau paparan.
Dengan cara ini, komponen induk akan menyimpan state dengan data, manakala komponen cucu kita akan menerima data ini melalui props dan pada masa yang sama akan mempunyai state sendiri untuk mengubah modnya.
Jadi, mari kita laksanakan apa yang diterangkan.
Komponen Products
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>;
}
Komponen Product
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>;
}
Komponen ProductField
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>;
}
Tugas Praktikal
Lakukan operasi yang serupa dengan komponen
Users dan User, yang telah anda buat
dalam pelajaran sebelumnya.