ฮุก useEffect และอาร์เรย์การพึ่งพา
ทำความเข้าใจว่า useEffect ทำงานเมื่อใด ควบคุมด้วยอาร์เรย์การพึ่งพา และล้างการสมัครรับข้อมูลหรือตัวจับเวลาด้วยการคืนฟังก์ชันล้างข้อมูล
ฮุก useEffect และอาร์เรย์การพึ่งพา เป็นบทเรียน React Native Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน React Native Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส React Native Academy มีบทเรียนทั้งหมด 4 บทเรียน
บางส่วนของบทเรียนนี้ยังไม่ได้รับการแปล และแสดงเป็นภาษาอังกฤษ
What is useEffect?
useEffect lets function components perform side effects: fetching data, setting up subscriptions, manipulating the DOM, starting timers, or calling native APIs. Side effects cannot be run directly in the render function because renders must be pure. useEffect runs after the component renders to the screen.
import { useEffect } from 'react';
function App() {
useEffect(() => {
console.log('Component rendered');
// Side effects go here
});
}The Dependency Array
The second argument to useEffect is the dependency array. React uses it to decide when to re-run the effect. If the dependency array is omitted, the effect runs after every render. If it is empty ([]), the effect runs once after the initial render. If it contains values, the effect re-runs whenever any of those values change.
// Runs after every render
useEffect(() => { ... });
// Runs once on mount
useEffect(() => { ... }, []);
// Runs on mount and whenever userId changes
useEffect(() => { ... }, [userId]);Fetching Data on Mount
The most common useEffect pattern is fetching data when a component first mounts. Pass an empty dependency array to ensure the fetch runs exactly once. Store the result in state and render it in the JSX. React calls the effect after the initial paint, so the component renders once with empty/loading state before the data arrives.
function PostsScreen() {
const [posts, setPosts] = useState([]);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/posts')
.then((res) => res.json())
.then((data) => setPosts(data));
}, []); // empty array = run once on mount
return <FlatList data={posts} ... />;
}Reactive Dependencies
When you want the effect to re-run whenever a value changes (like a search query or a user ID), list that value in the dependency array. React compares each dependency with its previous value after every render, and if any have changed, it re-runs the effect. This creates a reactive data flow: UI event → state update → effect re-runs.
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
fetch('/api/users/' + userId)
.then((res) => res.json())
.then((data) => setUser(data));
}, [userId]); // re-fetch whenever userId changes
if (!user) return <ActivityIndicator />;
return <Text>{user.name}</Text>;
}The Cleanup Function
Return a function from your effect to perform cleanup. React calls this cleanup function before re-running the effect (on dependency changes) and when the component unmounts. Use it to cancel subscriptions, clear timers, or abort fetch requests to prevent memory leaks and state updates on unmounted components.
useEffect(() => {
const timer = setInterval(() => {
setTime(Date.now());
}, 1000);
return () => clearInterval(timer); // cleanup on unmount or re-run
}, []);Cancelling Fetch Requests with AbortController
When a component unmounts before a fetch completes, React will warn about updating state on an unmounted component. Use the AbortController to cancel the in-flight fetch in the cleanup function. Catching the abort error (which is an AbortError) prevents it from being logged as an unexpected error.
useEffect(() => {
const controller = new AbortController();
fetch('/api/data', { signal: controller.signal })
.then((res) => res.json())
.then((data) => setData(data))
.catch((err) => {
if (err.name !== 'AbortError') setError(err);
});
return () => controller.abort();
}, []);Running Code Only on Unmount
To run code only when the component unmounts (like unsubscribing from an event listener), return a cleanup function from a useEffect with an empty dependency array. React calls the cleanup only when the component leaves the tree, never on subsequent renders.
useEffect(() => {
const subscription = eventEmitter.addListener('change', handler);
return () => {
subscription.remove(); // only on unmount
};
}, []); // empty array = mount-only effectMultiple useEffect Calls
You can and should use multiple useEffect calls in one component — one for each independent side effect. React runs them in the order they appear after every render. Keeping effects separated by concern makes the code easier to read and avoids complex dependency arrays that mix unrelated logic.
// Effect 1: fetch user data
useEffect(() => {
fetchUser(userId).then(setUser);
}, [userId]);
// Effect 2: analytics page view
useEffect(() => {
analytics.logScreenView('Profile');
}, []);
// Effect 3: sync title to header
useEffect(() => {
navigation.setOptions({ title: user?.name ?? 'Profile' });
}, [user, navigation]);Dependency Pitfalls: Missing Dependencies
A common bug is omitting a dependency from the array. The effect captures a stale value of the missing dependency and runs with outdated data. Always include every value from the component scope that is read inside the effect. ESLint's react-hooks/exhaustive-deps rule catches these automatically.
// Bug: fetchUser uses userId but it is not in deps
// If userId changes, the effect still runs with the old userId
useEffect(() => {
fetchUser(userId).then(setUser);
}, []); // Missing userId!
// Correct:
useEffect(() => {
fetchUser(userId).then(setUser);
}, [userId]);Avoiding Infinite Loops
If your effect updates state that is also listed as a dependency, you get an infinite loop: render → effect → state update → render → effect → .... Guard against this with a condition inside the effect, or restructure so the effect does not trigger the state update that caused it to run.
// Infinite loop: effect updates 'count' which is in deps
useEffect(() => {
setCount(count + 1); // triggers re-render → effect runs again
}, [count]);
// Fix: use functional updater — no need to list count as dep
useEffect(() => {
setCount((c) => c + 1);
}, []); // only runs onceComparing Effects to Lifecycle Methods
useEffect replaces all three classic class component lifecycle methods: componentDidMount (empty deps array), componentDidUpdate (with deps), and componentWillUnmount (cleanup function). One hook handles all three phases, keeping related logic together rather than spread across three separate methods.
useEffect(() => {
// componentDidMount equivalent — fetch initial data
fetchData();
return () => {
// componentWillUnmount equivalent — cancel subscriptions
cancelSubscription();
};
}, []); // runs once on mount, cleanup on unmountQuick Check
Test your understanding of the useEffect hook and dependency arrays from this lesson.
Lesson Recap
In this lesson you learned: useEffect runs side effects after render, the dependency array controls when the effect re-runs — empty means once on mount, and return a cleanup function to cancel subscriptions, timers, and fetch requests on unmount. Next up we make GET requests with Axios inside useEffect.
คำถามที่พบบ่อย
บทเรียน “ฮุก useEffect และอาร์เรย์การพึ่งพา” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ฮุก useEffect และอาร์เรย์การพึ่งพา” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส React Native Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส React Native Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ฮุก useEffect และอาร์เรย์การพึ่งพา”
ทำความเข้าใจว่า useEffect ทำงานเมื่อใด ควบคุมด้วยอาร์เรย์การพึ่งพา และล้างการสมัครรับข้อมูลหรือตัวจับเวลาด้วยการคืนฟังก์ชันล้างข้อมูล คุณปฏิบัติ React Native Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน React Native Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน React Native Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “ฮุก useEffect และอาร์เรย์การพึ่งพา” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน React Native Academy นี้ได้ไหม
ได้ บทเรียน React Native Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ฮุก useEffect และอาร์เรย์การพึ่งพา
- การส่งคำขอ GET ด้วย Axios
- การจัดการสถานะกำลังโหลดและข้อผิดพลาด
- POST, PUT และ DELETE ด้วย Axios