การเลื่อนสถานะขึ้น (Lifting State Up) ใน React

บ่อยครั้งที่คอมโพเนนต์หลายตัวต้องแสดงข้อมูลที่เปลี่ยนแปลงเดียวกัน ใน React แนะนำให้เลื่อนสถานะที่ใช้ร่วมกันขึ้นไปยังคอมโพเนนต์บรรพบุรุษร่วมที่ใกล้ที่สุด ลองดูตัวอย่าง

สมมติว่าเราต้องการสร้างเครื่องคำนวณอุณหภูมิของน้ำ มันจะประกอบด้วยอินพุต ให้ผู้ใช้ป้อนอุณหภูมิ และย่อหน้าที่จะแสดงผลลัพธ์: น้ำเป็นของเหลว น้ำเป็นของแข็ง น้ำเป็นก๊าซ

สมมติว่าเครื่องคิดเลขของเราเป็น คอมโพเนนต์คอนเทนเนอร์ Calculator:

jsxfunction Calculator() {
  return <div>
    
  </div>;
}

ให้นำอินพุตสำหรับป้อนอุณหภูมิออกมาเป็นคอมโพเนนต์ TempInp และนำย่อหน้าที่แสดงผลลัพธ์ออกมาเป็นคอมโพเนนต์ Verdict:

jsxfunction Calculator() {
  return <div>
    <Verdict />
    <TempInp />
  </div>;
}

ง่ายที่จะเข้าใจว่า ทั้ง TempInp และ Verdict ควร มีสถานะ (state) ที่เก็บอุณหภูมิ ในขณะเดียวกันก็สมเหตุสมผล ว่ามันควรเป็นอุณหภูมิเดียวกัน: ขณะที่ป้อนข้อมูลในอินพุตควร แสดงผลลัพธ์ออกมา

ในกรณีเช่นนี้ แนะนำให้ใช้เทคนิคที่ เรียกว่า การเลื่อนสถานะขึ้น (Lifting State Up): สถานะ ที่ใช้ร่วมกันระหว่างสอง (หรือมากกว่า) คอมโพเนนต์จะถูกเลื่อนขึ้น ไปยังคอมโพเนนต์บรรพบุรุษร่วมของพวกมัน

ในกรณีของเรา ผลลัพธ์คือ สถานะอุณหภูมิ ควรเป็นของคอมโพเนนต์ Calculator ซึ่งจะส่งผ่านมันไปยัง TempInp และ Verdict ในรูปของพร็อปส์ (props):

jsxfunction Calculator() {
  const [temp, setTemp] = useState(0);
  
  return <div>
    <Verdict temp={temp} />
    <TempInp temp={temp} />
  </div>;
}

ในคอมโพเนนต์ TempInp ควรมีอินพุต สำหรับเปลี่ยนอุณหภูมิ แต่เนื่องจาก อุณหภูมินี้เป็นพร็อปส์ของคอมโพเนนต์นี้ ดังนั้นการเปลี่ยนค่า โดยตรงใน TempInp จึงทำไม่ได้ วิธีที่ถูกต้องคือส่งฟังก์ชันพิเศษสำหรับ เปลี่ยนอุณหภูมิจากคอมโพเนนต์ Calculator ลงมา:

jsxfunction Calculator() {
  const [temp, setTemp] = useState(0);
  
  function changeTemp(event) {
    setTemp(event.target.value);
  }
  
  return <div>
    <Verdict temp={temp} />
    <TempInp temp={temp} changeTemp={changeTemp} />
  </div>;
}

อย่างไรก็ตาม ไม่จำเป็นต้องสร้างฟังก์ชันใหม่ แต่สามารถส่งฟังก์ชัน setTemp ลงไปในคอมโพเนนต์ลูกได้:

jsxfunction Calculator() {
  const [temp, setTemp] = useState(0);
  
  return <div>
    <Verdict temp={temp} />
    <TempInp temp={temp} setTemp={setTemp} />
  </div>;
}
Задание 1

เขียนการทำงานของคอมโพเนนต์ TempInp และ Verdict

Задание 2

คิดโจทย์ 3 ข้อ ที่จำเป็นต้อง ใช้การเลื่อนสถานะขึ้น เขียนคำตอบ ของโจทย์เหล่านี้