Kodokon kodokon.com

ฟอร์มแบบควบคุม (Controlled forms)

เรียนรู้การขับเคลื่อนทุกฟิลด์ของฟอร์มจาก state ของ React เพื่อให้คุณตรวจสอบและส่งข้อมูลที่เชื่อถือได้

8 นาที · 3 คำถาม

เปิดบทเรียนนี้ใน Kodokon

ใน React ฟอร์มจะคาดเดาได้เมื่อทุกฟิลด์เป็นแบบ ควบคุม (controlled): ค่าที่แสดงมาจาก state ของคอมโพเนนต์ และทุกครั้งที่กดแป้นพิมพ์จะผ่าน onChange เพื่ออัปเดต state นั้น DOM ไม่ใช่แหล่งความจริงอีกต่อไป - state ของคุณต่างหากที่เป็น ในทางปฏิบัติ คุณผูก prop value เข้ากับตัวแปร state และจัดเตรียม handler ที่เรียกฟังก์ชันอัปเดต

JSX
import { useState } from "react";

function EmailField() {
  const [email, setEmail] = useState("");

  return (
    <input
      type="email"
      value={email}
      onChange={(e) => setEmail(e.target.value)}
    />
  );
}
ฟิลด์แบบควบคุม: value อ่านค่าจาก state ส่วน onChange เป็นตัวเขียนค่า

ฟอร์มจริงมักไม่ได้มีฟิลด์เดียว แทนที่จะเรียก useState ซ้อนกันหลายครั้ง ให้รวมค่าต่าง ๆ ไว้ในออบเจ็กต์เดียวและเขียน handler แบบทั่วไป (generic handler) แอตทริบิวต์ name ของแต่ละฟิลด์ต้องตรงกับ key ของออบเจ็กต์อย่างเป๊ะ ๆ: นั่นคือสิ่งที่บอก handler ว่าจะอัปเดตพรอเพอร์ตีไหน

JSX
const [form, setForm] = useState({
  username: "",
  password: "",
});

function handleChange(e) {
  const { name, value } = e.target;
  setForm((prev) => ({ ...prev, [name]: value }));
}
handler เดียวสำหรับทุกฟิลด์ในฟอร์ม

เหลือแต่การส่งข้อมูล โดยค่าเริ่มต้น เบราว์เซอร์จะรีโหลดหน้าเมื่อฟอร์มถูกส่ง: ให้เรียก e.preventDefault() ที่บรรทัดบนสุดของ handler onSubmit ของคุณ อีกทั้งยังเป็นจุดที่เหมาะจะ ตรวจสอบข้อมูล ก่อนส่งด้วย เพราะ state ของฟอร์มทั้งหมดอยู่ในมือแล้ว

JSX
function handleSubmit(e) {
  e.preventDefault();
  if (form.username.trim() === "") {
    alert("Username is required.");
    return;
  }
  console.log("Submitting:", form);
}

return (
  <form onSubmit={handleSubmit}>
    <input
      name="username"
      value={form.username}
      onChange={handleChange}
    />
    <button type="submit">Create account</button>
  </form>
);
ตรวจสอบก่อน แล้วจึงส่ง โดยไม่รีโหลดหน้า

ทดสอบความรู้

ตรวจสอบว่าคุณจำประเด็นสำคัญของบทเรียนนี้ได้ครบถ้วน

  1. อะไรคือสิ่งที่นิยามฟิลด์แบบควบคุมใน React?
    • ค่าของมันถูกเก็บไว้ใน DOM และอ่านด้วย ref
    • ค่าของมันมาจาก state และทุกครั้งที่กดแป้นพิมพ์จะผ่าน onChange
    • มันเป็นแบบอ่านอย่างเดียวจนกว่าฟอร์มจะถูกส่ง
    • มันตรวจสอบข้อมูลที่คุณพิมพ์โดยอัตโนมัติ
  2. คุณส่ง value={email} ไปยัง <input> โดยไม่ระบุ onChange จะเกิดอะไรขึ้น?
    • ฟิลด์หยุดนิ่ง: พิมพ์อะไรก็ไม่มีผลอีกต่อไป
    • ฟิลด์ทำงานปกติ React จัดการ input ให้เอง
    • คอมโพเนนต์พังตอนเรนเดอร์ครั้งแรก
  3. e.preventDefault() ใน handler onSubmit มีไว้เพื่ออะไร?
    • เพื่อป้องกันการรีโหลดหน้าที่เกิดจากการส่งฟอร์มแบบเนทีฟ
    • เพื่อล้างฟิลด์ของฟอร์มโดยอัตโนมัติ
    • เพื่อหยุดไม่ให้อีเวนต์แพร่ไปยังคอมโพเนนต์แม่
    • เพื่อปิดการตรวจสอบ HTML ของเบราว์เซอร์