วิธีการทำงานผ่านสเตตของคอมโพเนนต์ลูกใน React
ให้อาร์เรย์ผลิตภัณฑ์ของเราตอนนี้มีลักษณะ ดังต่อไปนี้:
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'},
];
มาแสดงผลิตภัณฑ์เหล่านี้ในรูปแบบ HTML
ตารางกัน และทำให้เมื่อคลิกที่
เซลล์ใดๆ ของตาราง ในเซลล์นั้นจะปรากฏ
input สำหรับแก้ไข เพื่อแก้ปัญหา
เราจะสร้าง 3 คอมโพเนนต์
คอมโพเนนต์ Products จะเก็บสเตต
ที่มีผลิตภัณฑ์และใช้คอมโพเนนต์ Product
เพื่อแสดงผลผลิตภัณฑ์ คอมโพเนนต์ Product
จะใช้คอมโพเนนต์
ProductField ในการแสดงผลฟิลด์
ของผลิตภัณฑ์ (ชื่อ ราคา หมวดหมู่)
คอมโพเนนต์ ProductField จะ
แสดงข้อความของฟิลด์ หรือ input สำหรับ
แก้ไข
โดยให้โหมดแก้ไข
หรือการแสดงผล ถูกควบคุมโดยสเตต
ของคอมโพเนนต์นี้
นั่นคือเราจะไม่เก็บโหมดในสเตตของตัวหลัก ที่นั่นมันจะไม่สะดวกมาก เพราะ เราจะต้องระบุโหมดสำหรับแต่ละ ฟิลด์ของผลิตภัณฑ์ ซึ่งจะเปลี่ยนสเตตของเรา ให้กลายเป็นอะไรแบบนี้:
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},
],
]
อย่างไรก็ตาม เราจะไม่ทำสเตตแบบนั้น
แต่จะใช้แบบเดิม
เพียงแค่แต่ละ
อินสแตนซ์ของคอมโพเนนต์ ProductField
ด้วยสเตตของตัวเองจะควบคุม
โหมด: แก้ไข หรือแสดง
ดังนั้นผลลัพธ์ที่ได้คือ คอมโพเนนต์หลัก จะเก็บสเตตที่มีข้อมูล และคอมโพเนนต์ลูกหลานของเราจะได้รับ ข้อมูลเหล่านี้ ผ่าน props และจะมี สเตตของตัวเองสำหรับเปลี่ยนโหมดของตัวเอง
มาเริ่มทำตามที่อธิบายกัน
คอมโพเนนต์ 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>;
}
คอมโพเนนต์ 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>;
}
คอมโพเนนต์ 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>;
}
งานปฏิบัติ
ดำเนินการที่คล้ายกันกับคอมโพเนนต์
Users และ User ที่คุณสร้าง
ในบทเรียนก่อนหน้านี้