- เบื้องต้นเกี่ยวกับการจัดการเหตุการณ์ (Event Handling)
- ระบบเหตุการณ์สังเคราะห์ (Synthetic Event System) ReactJS
- การจัดการเหตุการณ์ใน ReactJS
- การกำหนดตัวจัดการเหตุการณ์ (Defining Event Handlers)
- การจัดการเหตุการณ์และคำหลัก ‘this’
- จัดการกับเหตุการณ์ที่มีงอาร์กิวเมนต์ (Handling Events with Arguments)
- การรวมเหตุการณ์ (Event Pooling)
ReactJS ซึ่งเป็นไลบรารีอันทรงพลังสำหรับสร้างส่วนต่อประสานกับผู้ใช้ ได้กลายเป็นโซลูชันที่ตอบโจทย์สำหรับนักพัฒนาทั่วโลก ด้วยเหตุนี้ จึงมีความต้องการเพิ่มขึ้นอย่างมากในการทำความเข้าใจพื้นฐานสำหรับทั้งการทำเว็บ ReactJS และทำแอพแบบไดนามิก หนึ่งในส่วนสำคัญของเส้นทางการเรียนรู้นี้คือการทำความเข้าใจวิธีจัดการกับเหตุการณ์ใน ReactJS
1. เบื้องต้นเกี่ยวกับการจัดการเหตุการณ์ (Event Handling)
การจัดการเหตุการณ์หมายถึงกระบวนการจัดการการโต้ตอบของผู้ใช้ที่เกิดขึ้นภายในแอปพลิเคชัน การโต้ตอบเหล่านี้อาจรวมถึงการคลิก การเลื่อน การป้อนข้อมูลด้วยแป้นพิมพ์ การส่งแบบฟอร์ม และอื่นๆ เมื่อออกแบบแอปพลิเคชันเชิงโต้ตอบ การทำความเข้าใจเกี่ยวกับการจัดการเหตุการณ์เป็นสิ่งสำคัญ เนื่องจากจะช่วยตอบสนองต่อการกระทำของผู้ใช้และสร้างประสบการณ์ผู้ใช้ที่ลื่นไหล
ใน JavaScript เราจัดการกับเหตุการณ์โดยการเพิ่มตัวรับฟังเหตุการณ์ให้กับองค์ประกอบและระบุการดำเนินการที่จะดำเนินการเมื่อเหตุการณ์เหล่านี้เกิดขึ้น กระบวนการนี้คล้ายกันใน ReactJS แต่มีความแตกต่างเล็กน้อยเนื่องจากธรรมชาติของระบบเหตุการณ์สังเคราะห์ที่ React นำไปใช้
2. ระบบเหตุการณ์สังเคราะห์ (Synthetic Event System) ReactJS
React มีระบบเหตุการณ์สังเคราะห์ซึ่งหมายความว่ามีระบบเหตุการณ์ของตัวเอง มันล้อมรอบระบบเหตุการณ์ดั้งเดิมในเบราว์เซอร์ โดยมีอินเทอร์เฟซข้ามเบราว์เซอร์สำหรับจัดการเหตุการณ์ โดยพื้นฐานแล้ว เหตุการณ์สังเคราะห์ของ React จะรวมพฤติกรรมของเบราว์เซอร์ต่างๆ ไว้ใน API เดียว เพื่อให้แน่ใจว่าเหตุการณ์จะทำงานสอดคล้องกันในทุกเบราว์เซอร์
3. การจัดการเหตุการณ์ใน ReactJS
การจัดการเหตุการณ์ใน React นั้นคล้ายกับการจัดการเหตุการณ์บนองค์ประกอบ DOM ในวานิลลา JavaScript อย่างไรก็ตาม มีความแตกต่างทางไวยากรณ์บางประการ เหตุการณ์การตอบสนองถูกตั้งชื่อโดยใช้ camelCase แทนที่จะเป็นตัวพิมพ์เล็ก และด้วย JSX คุณจะส่งฟังก์ชันเป็นตัวจัดการเหตุการณ์ แทนที่จะเป็นสตริง
ตัวอย่างเช่น HTML:
<button onclick="handleClick()">
Click me
</button>
จะเขียนใน React เป็น:
<button onClick={handleClick}>
Click me
</button>
ในตัวอย่าง React handleClick
ฟังก์ชันจะถูกส่งผ่านโดยตรง ไม่ใช่สตริง นี่เป็นข้อแตกต่างที่สำคัญและหนึ่งในวิธีที่ JSX แตกต่างจาก HTML
4. การกำหนดตัวจัดการเหตุการณ์ (Defining Event Handlers)
ตัวจัดการเหตุการณ์ใน React สามารถกำหนดเป็นคลาสเมธอดในคลาสคอมโพเนนต์หรือฟังก์ชันในคอมโพเนนต์การทำงาน เพื่อแสดงให้เห็น ต่อไปนี้เป็นส่วนประกอบของคลาสอย่างง่ายที่มีตัวจัดการเหตุการณ์การคลิกปุ่ม:
class MyButton extends React.Component {
handleClick() {
console.log('Button clicked');
}
render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
}
และนี่คือองค์ประกอบการทำงานที่เทียบเท่ากับตัวจัดการเหตุการณ์การคลิกปุ่ม:
function MyButton() {
const handleClick = () => {
console.log('Button clicked');
}
return (
<button onClick={handleClick}>
Click me
</button>
);
}
คอมโพเนนต์ทั้งสองจะบันทึก “Button clicked” ไปยังคอนโซลเมื่อคลิกปุ่ม
5. การจัดการเหตุการณ์และคำหลัก ‘this’
ใน JavaScript เมธอดคลาสจะไม่ถูกผูกไว้โดยค่าเริ่มต้น หากคุณส่งผ่านเมธอดโดยไม่()
ได้ผูกไว้ this
จะ this
เป็น undefined
เวลาที่เรียกใช้ฟังก์ชันจริง นี่เป็นที่มาของความสับสนสำหรับนักพัฒนาที่เพิ่งเริ่มใช้ React
วิธีมาตรฐานในการแก้ไขปัญหานี้ในส่วนประกอบของคลาส React คือการผูกฟังก์ชันตัวจัดการเหตุการณ์ในตัวสร้าง:
class MyButton extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log('Button clicked');
}
render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
}
หรือคุณสามารถกำหนดตัวจัดการเหตุการณ์เป็นฟังก์ชันลูกศร ซึ่งจะเชื่อมโยงโดยอัตโนมัติ this
:
class MyButton extends React.Component {
handleClick = () => {
console.log('Button clicked');
}
render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
}
ในองค์ประกอบการทำงาน this
คีย์เวิร์ดไม่ใช่ปัญหา เพราะคุณสามารถใช้ useState
hook เพื่อจัดการการเปลี่ยนแปลงสถานะได้
6. จัดการกับเหตุการณ์ที่มีงอาร์กิวเมนต์ (Handling Events with Arguments)
บางครั้ง คุณต้องส่งอาร์กิวเมนต์เพิ่มเติมไปยังตัวจัดการเหตุการณ์ ตัวอย่างเช่น หาก ID เป็นส่วนหนึ่งขององค์ประกอบที่เกิดซ้ำ และคุณจำเป็นต้องทราบว่า ID ใดถูกคลิก ในองค์ประกอบลูป คุณสามารถส่งอาร์กิวเมนต์ได้โดยตรงดังนี้:
function List({ items }) {
const handleClick = (id) => {
console.log('Item clicked: ' + id);
}
return (
<ul>
{items.map(item => (
<li key={item.id} onClick={() => handleClick(item.id)}>
{item.name}
</li>
))}
</ul>
);
}
7. การรวมเหตุการณ์ (Event Pooling)
ใน React จะมีการรวมเหตุการณ์สังเคราะห์ ซึ่งหมายความว่าวัตถุ SyntheticEvent จะถูกนำมาใช้ซ้ำและคุณสมบัติทั้งหมดจะถูกทำให้เป็นโมฆะหลังจากเรียกใช้การเรียกกลับของเหตุการณ์ ด้วยเหตุนี้ คุณไม่สามารถเข้าถึงเหตุการณ์ในแบบอะซิงโครนัสได้
function MyButton() {
const handleClick = (event) => {
console.log(event); // => nullified object.
console.log(event.type); // => "click"
const eventType = event.type; // => "click"
setTimeout(function() {
console.log(event.type); // => null
console.log(eventType); // => "click"
}, 0);
// Won't work. this.state.clickEvent will only contain null values.
this.setState({clickEvent: event});
};
return (
<button onClick={handleClick}>
Click me
</button>
);
}
ในการแก้ไขปัญหานี้ คุณสามารถใช้ event.persist()
. จะลบเหตุการณ์สังเคราะห์ออกจากกลุ่มและอนุญาตให้มีการอ้างอิงถึงเหตุการณ์โดยรหัสผู้ใช้
ReactJS มอบวิธีที่มีประสิทธิภาพแต่ใช้งานง่ายในการจัดการเหตุการณ์ที่ผู้ใช้เรียกใช้ในแอปพลิเคชันที่คุณสร้างขึ้น การทำความเข้าใจเกี่ยวกับการจัดการเหตุการณ์เป็นสิ่งสำคัญเมื่อคุณทำเว็บ ReactJS และทำแอพ หรือออกแบบอินเทอร์เฟซแบบโต้ตอบใดๆ ด้วยคำแนะนำที่ครอบคลุมเกี่ยวกับการจัดการเหตุการณ์ใน ReactJS คุณควรมีความพร้อมในการเริ่มทำเว็บ ReactJS และทำแอพแบบไดนามิกที่โต้ตอบได้โดยใช้ ReactJS
ระบบเหตุการณ์ของ React นั้นไม่เหมือนใคร แต่ก็คุ้นเคย และเชื่อมโยงเข้ากับลักษณะการประกาศของไลบรารีเอง ด้วยความเข้าใจเหตุการณ์ที่ดี คุณก็เข้าใกล้การควบคุม React ไปอีกขั้น