useEffect, useLayoutEffect และ useEffectEvent: การเปรียบเทียบ Data Fetching Hooks ใน React
React hooks เป็นวิธีที่มีประสิทธิภาพในการจัดการผลข้างเคียงในส่วนประกอบ React hooks ที่พบบ่อยที่สุดสามประการสำหรับจัดการกับผลข้างเคียงคือ useEffect, useLayoutEffect และ useEffectEvent ตะขอแต่ละอันมีกรณีการใช้งานเฉพาะตัว ดังนั้นการเลือกตะขอให้เหมาะกับงานจึงเป็นสิ่งสำคัญ
ตะขอ useEffect
ฟังก์ชันการเรนเดอร์เอฟเฟกต์และรายการการพึ่งพา
ฟังก์ชันเอฟเฟกต์จะห่อหุ้มโค้ดที่รับผิดชอบในการสร้างผลข้างเคียง ในขณะที่อาร์เรย์การขึ้นต่อกันจะกำหนดว่าฟังก์ชันดังกล่าวควรถูกดำเนินการเมื่อใด ในกรณีที่อาร์เรย์การพึ่งพายังคงไม่มีเนื้อหา ฟังก์ชันเอฟเฟกต์จะดำเนินการในระหว่างการเรนเดอร์ครั้งแรกของส่วนประกอบเท่านั้น ในทางกลับกัน หากอาร์เรย์การขึ้นต่อกันมีการแก้ไขใดๆ ฟังก์ชันเอฟเฟกต์จะถูกทริกเกอร์ให้ทำงานใหม่พร้อมกับการแก้ไขแต่ละครั้ง
ที่จริงแล้ว ภาพประกอบที่สำคัญของการใช้ฮุก useEffect
สำหรับการดึงข้อมูลมีดังต่อไปนี้:
import React from "react";
function App() {
const [data, setData] = React.useState([]);
React.useEffect(() => {
fetch("<https://jsonplaceholder.typicode.com/posts>")
.then((response) => response.json())
.then((data) => setData(data));
}, []);
return (
<div className="app">
{data.map((item) => (
<div key={item.id}>{item.title}</div>
))}
</div>
);
}
export default App;
ตัวอย่างนี้แสดงส่วนประกอบ React เชิงฟังก์ชัน ซึ่งเรียกว่าส่วนประกอบ “แอป” ซึ่งใช้ฮุก “useEffect” เพื่อดึงข้อมูลจาก API ภายนอก โดยเฉพาะอย่างยิ่ง ตัวจัดการเอฟเฟกต์ที่เกี่ยวข้องกับฮุค “useEffect” จะดึงข้อมูลตัวอย่างจาก JSONPlaceholder API ประมวลผลการตอบสนองของ JSON และอัปเดตสถานะ “ข้อมูล” ด้วยข้อมูลที่ได้รับในภายหลัง
เมื่อคำนึงถึงสถานะปัจจุบันของข้อมูลแอปพลิเคชันของเรา แอปจะแสดงแอตทริบิวต์ชื่อที่เกี่ยวข้องกับทุกรายการที่เกี่ยวข้องภายในข้อมูลนั้น
ลักษณะของ useEffect Hook
แอปพลิเคชันได้รับการออกแบบโดยคำนึงถึงการทำงานแบบอะซิงโครนัสและรวมฟังก์ชันการทำงานนี้ไว้ด้วยกัน ส่งผลให้ได้รับประสบการณ์ที่ราบรื่นเมื่อเรียกข้อมูล
การใช้งานฮุก useEffect
มีกำหนดจะเกิดขึ้นหลังจากเสร็จสิ้นกระบวนการเรนเดอร์สำหรับส่วนประกอบที่กำหนด ดังนั้นจึงรับประกันได้ว่าฮุกดังกล่าวจะไม่ขัดขวางหรือขัดขวางอินเทอร์เฟซผู้ใช้ในช่วงเวลานี้
คำสั่ง
เสนอแนวทางที่มีประสิทธิภาพสำหรับการดำเนินงานล้างข้อมูลผ่านการจัดเตรียมฟังก์ชันที่จะถูกเรียกใช้โดยอัตโนมัติเมื่อผู้ฟังหรือสมัครสมาชิกเสร็จสิ้น ฟังก์ชันดังกล่าวอาจเป็นประโยชน์อย่างยิ่งในสถานการณ์ที่การปิดและปล่อยทรัพยากรอย่างมีประสิทธิภาพเป็นสิ่งสำคัญยิ่ง เช่น ในกรณีที่เกี่ยวข้องกับผู้ฟังหรือการสมัครรับข้อมูล
ตะขอ useLayoutEffect
การใช้ hook useLayoutEffect
จะสะท้อนการทำงานของ hook useEffect
อย่างใกล้ชิด อย่างไรก็ตาม มันทำงานพร้อมกันหลังจากการเปลี่ยนแปลง DOM ทั้งหมด ด้วยเหตุนี้ ฟังก์ชันนี้จึงทำงานก่อนที่เบราว์เซอร์จะเรนเดอร์การแสดงภาพบนหน้าจอได้ จึงทำให้มีข้อได้เปรียบอย่างมากสำหรับการดำเนินการที่จำเป็นต้องมีการจัดการที่เข้มงวดของโครงสร้าง Document Object Model (DOM) และคุณลักษณะการจัดรูปแบบ ซึ่งรวมถึงแต่ไม่จำกัดเพียงการกำหนดขนาด ขององค์ประกอบเฉพาะ การปรับขนาดขององค์ประกอบ หรือการจัดวางเชิงพื้นที่ขององค์ประกอบดังกล่าวผ่านเทคนิคแอนิเมชั่น
การใช้ฮุก useLayoutEffect
ทำให้เราสามารถปรับเปลี่ยนขนาดของส่วนประกอบปุ่มได้ดังที่แสดงด้านล่าง:
import React from "react";
function App() {
const button = React.useRef();
React.useLayoutEffect(() => {
const { width } = button.current.getBoundingClientRect();
button.current.style.width = `${width \+ 12}px`;
}, []);
return (
<div className="app">
<button ref={button}>Click Me</button>
</div>
);
}
export default App;
ข้อมูลโค้ดที่กล่าวมาข้างต้นจะขยายขนาดของส่วนประกอบปุ่มอีก 12 หน่วยโดยใช้ยูทิลิตีการทำงาน useLayoutEffect
ด้วยเหตุนี้ การกำหนดค่านี้รับประกันว่าความกว้างที่ปรับแล้วจะถูกนำไปใช้กับปุ่มก่อนที่จะปรากฏให้เห็นบนอุปกรณ์แสดงผลของผู้ใช้
ลักษณะของ useLayoutEffect Hook
การดำเนินการโค้ด JavaScript แบบซิงโครนัสช่วยให้แน่ใจว่าการดำเนินการเกิดขึ้นตามลำดับโดยไม่รบกวนอินเทอร์เฟซผู้ใช้ อย่างไรก็ตาม วิธีการนี้อาจส่งผลให้เกิดความล่าช้าหรือการอุดตันของ UI เนื่องจากลักษณะการดำเนินการบางอย่างที่ใช้เวลานาน
การดำเนินการอ่าน/เขียน DOM ได้รับการออกแบบมาอย่างเหมาะสมเพื่อการเข้าถึง Document Object Model ได้ทันทีสำหรับทั้งการอ่านและการเขียนข้อมูล โดยเฉพาะอย่างยิ่งเมื่อความสะดวกในการสังเกตการแก้ไขก่อนกระบวนการทาสีใหม่ของเบราว์เซอร์เป็นสิ่งสำคัญอันดับแรก
ตะขอ useEffectEvent
การใช้ hook useEffectEvent
ถือเป็นวิธีแก้ปัญหาที่มีประสิทธิภาพสำหรับปัญหาการพึ่งพาที่ท้าทายซึ่งอยู่ภายใน hook useEffect
ทั่วไป ดูเหมือนว่าผู้ที่เชี่ยวชาญการทำงานของ useEffect
อาจพบว่าตนเองต้องต่อสู้กับความซับซ้อนของอาร์เรย์ที่ต้องพึ่งพา ซึ่งในบางครั้งจำเป็นต้องรวมองค์ประกอบต่างๆ นอกเหนือจากที่จำเป็นอย่างยิ่งสำหรับการทำงานที่เหมาะสม
ตัวอย่างเช่น:
import React from "react";
function App() {
const connect = (url) => {
// logic for connecting to the url
};
const logConnection = (message, loginOptions) => {
// logic for logging the connection details
};
const onConnected = (url, loginOptions) => {
logConnection(`Connected to ${url}`, loginOptions);
};
React.useEffect(() => {
const device = connect(url);
device.onConnected(() => {
onConnected(url);
});
return () => {
device.disconnect();
};
}, [url, onConnected]);
return <div></div>;
}
export default App;
รหัสปัจจุบันแสดงการทำงานของ
ฟังก์ชั่น hook useEffect
โดยการเรียกใช้เมธอด เชื่อมต่อ
และสร้างฟังก์ชันการโทรกลับแบบอะซิงโครนัส"onConnected"ซึ่งจะดำเนินการเมื่ออุปกรณ์ทริกเกอร์เหตุการณ์"onConnected"ต่อจากนั้น การเรียกกลับนี้จะดำเนินการบันทึกการดำเนินการที่สร้างข้อความการเชื่อมต่อ นอกจากนี้ยังมีฟังก์ชันการรื้อถอนซึ่งจะมีผลเมื่อถอดส่วนประกอบออก จึงถือว่ามีหน้าที่รับผิดชอบในการตัดการเชื่อมต่อกับอุปกรณ์
DependencyArray รวมเอาทั้ง URL และเครื่องจัดการเหตุการณ์ที่เรียกว่า “onConnected” แต่ละครั้งที่มีการแสดงผลองค์ประกอบของแอป จะสร้างฟังก์ชันเฉพาะนี้แบบไดนามิก ด้วยเหตุนี้ React hook “useEffect” จะต้องผ่านกระบวนการวนซ้ำ โดยที่วัตถุประสงค์หลักคือการอัปเดตสถานะของส่วนประกอบแอปซ้ำๆ
หนึ่งในวิธีที่มีประสิทธิภาพในการแก้ไขปัญหาของลูป useEffect คือการใช้ตะขอ useEffectEvent ซึ่งช่วยให้สามารถแก้ไขปัญหาได้อย่างคล่องตัวโดยไม่ต้องสร้างภาระให้กับอาร์เรย์การขึ้นต่อกันด้วยค่าที่ไม่รับประกันเพิ่มเติม
import React from "react";
function App() {
const connect = (url) => {
// logic for connecting to the URL
};
const logConnection = (message, loginOptions) => {
// logic for logging the connection details
};
const onConnected = React.useEffectEvent((url, loginOptions) => {
logConnection(`Connected to ${url}`, loginOptions);
});
React.useEffect(() => {
const device = connect(url);
device.onConnected(() => {
onConnected(url);
});
return () => {
device.disconnect();
};
}, [url]);
return <div></div>;
}
export default App;
ด้วยการใช้ hook useEffectEvent
เพื่อรวมฟังก์ชัน onConnected
เรารับรองว่าพารามิเตอร์ message
และ loginOptions
จะเป็นข้อมูลล่าสุดเสมอเมื่อส่งผ่านไปยัง hook useEffect
ผลที่ตามมาคือสิ่งหลังไม่ต้องพึ่งพาสิ่งแรกหรือพารามิเตอร์ใดๆ ที่ให้มาอีกต่อไป
เมื่อใช้ฮุก useEffect
อาจเป็นประโยชน์ที่จะอาศัยค่าเฉพาะในการทริกเกอร์เอฟเฟกต์ แม้ว่าเอฟเฟกต์นั้นจำเป็นต้องมีค่าเพิ่มเติมซึ่งอาจไม่เป็นที่ต้องการสำหรับการขึ้นต่อกันภายใน useEffect
ลักษณะของ useEffectEvent Hook
ระบบมีความเป็นเลิศในการจัดการกับผลที่ตามมาที่เกิดจากเหตุการณ์
การใช้ฮุค useEffect
เข้ากันไม่ได้กับฟังก์ชันการจัดการเหตุการณ์ เช่น onClick
, onChange
และอื่นๆ เนื่องจากเหตุการณ์เหล่านี้ถูกกระตุ้นโดยการโต้ตอบของผู้ใช้ แทนที่จะเป็นการขึ้นต่อกันเชิงโต้ตอบที่สามารถตรวจสอบการเปลี่ยนแปลงได้โดย React
hook useEffect
ซึ่งเป็นเครื่องมือที่ทรงพลังและอเนกประสงค์สำหรับจัดการผลข้างเคียงในส่วนประกอบการทำงาน ยังคงเป็นฟีเจอร์ทดลองใน React เวอร์ชันสูงสุด 18 ควรสังเกตว่าความพร้อมใช้งานอาจแตกต่างกันไปตามรีลีสหรือบิวด์ของ React ที่แตกต่างกัน
เมื่อใดควรใช้ตะขออันไหน?
hooks การดึงข้อมูลแต่ละอันมีการบังคับใช้เฉพาะของตัวเอง ขึ้นอยู่กับสถานการณ์เฉพาะ
การใช้ฮุก useEffect
ใน React มอบโซลูชันที่เหมาะสมสำหรับการดึงข้อมูลและอัปเดตข้อมูลภายในส่วนประกอบ เนื่องจากช่วยให้สามารถจัดการการดำเนินการแบบอะซิงโครนัสได้อย่างมีประสิทธิภาพ ขณะเดียวกันก็รักษาโค้ดเบสที่สะอาดและเป็นระเบียบ
เมื่อจำเป็นต้องทำการแก้ไขโดยตรงไปยัง Document Object Model (DOM) ในลักษณะที่ต้องแสดงการเปลี่ยนแปลงทันที ขอแนะนำให้ใช้ useLayoutEffect
ฟังก์ชันนี้ช่วยให้สามารถจัดการงานดังกล่าวได้อย่างมีประสิทธิภาพ โดยทำให้แน่ใจว่าการดำเนินการที่ระบุได้รับการดำเนินการหลังจากการเรนเดอร์ครั้งแรก และก่อนที่จะเกิดการอัพเดตหรือรีโฟลว์ในภายหลัง
การใช้ฮุก useEffect
สำหรับการดำเนินการแบบน้ำหนักเบาไม่เป็นอุปสรรคต่อการขัดขวางอินเทอร์เฟซผู้ใช้ ช่วยให้ดำเนินการได้อย่างง่ายดายและสะดวกสบาย
การใช้ผลข้างเคียงที่ขับเคลื่อนด้วยเหตุการณ์สามารถทำได้โดยการใช้ทั้งฮุก useEffectEvent
สำหรับการจับและจัดการเหตุการณ์ เช่นเดียวกับฮุก useEffect
สำหรับการดำเนินการผลข้างเคียงที่จำเป็นเพื่อตอบสนองต่อเหตุการณ์เหล่านั้น
จัดการผลข้างเคียงอย่างมีประสิทธิภาพ
การใช้ React hooks จะเผยให้เห็นศักยภาพที่หลากหลาย และการทำความเข้าใจความแตกต่างระหว่าง useEffect, useLayoutEffect และ useEffectEvent hooks สามารถมีอิทธิพลอย่างมากต่อวิธีจัดการผลข้างเคียงและการจัดการ DOM จำเป็นต้องพิจารณาข้อกำหนดเบื้องต้นและการขยายสาขาเฉพาะของ hooks เหล่านี้เพื่อสร้างโปรแกรมซอฟต์แวร์ที่เน้นผู้ใช้เป็นศูนย์กลาง