๐Ÿ’ก 07. useEffect ํŒŒ๊ดดํ•˜๊ธฐ (3): Race Condition ๋ฐฉ์–ด

๐Ÿ“‹ ๊ฐœ์š”

๋น ๋ฅด๊ฒŒ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ดํƒˆํ•˜๊ฑฐ๋‚˜ ๋น„๋™๊ธฐ ์š”์ฒญ ํƒ€์ด๋ฐ์ด ๊ผฌ์˜€์„ ๋•Œ ์˜›๋‚  ๋ฐ์ดํ„ฐ๊ฐ€ ํ™”๋ฉด์„ ๋ฎ์–ด๋ฒ„๋ฆฌ๋Š” ๋ฒ„๊ทธ(Race Condition)๋ฅผ ํŒŒ๊ดดํ•˜๋Š” Cleanup ๊ธฐ์ˆ ์„ ๋ฐฐ์›๋‹ˆ๋‹ค.

๐ŸŽฏ ์ด ์„น์…˜์„ ์ฝ๊ณ  ๋‚˜๋ฉด:

  • ํ”„๋กœํ•„์ด๋‚˜ ํƒญ์„ ๋น ๋ฅด๊ฒŒ ์ „ํ™˜ํ•  ๋•Œ A ์œ ์ € ์–ผ๊ตด์— B ์œ ์ € ์ด๋ฆ„์ด ๋œจ๋Š” ๊ธฐ๊ดดํ•œ ๋ฒ„๊ทธ(Race Condition) ์›์ธ์„ ๊ฟฐ๋šซ์„ ์ˆ˜ ์žˆ๋‹ค.
  • useEffect์˜ ๋ฐ˜ํ™˜ ํ•จ์ˆ˜์ธ ํด๋ฆฐ์—…(Cleanup, ๋’ท์ •๋ฆฌ) ํ•จ์ˆ˜๊ฐ€ ์–ธ์ œ ํŠธ๋ฆฌ๊ฑฐ๋˜๋Š”์ง€ 100% ์ดํ•ดํ•œ๋‹ค.
  • ๋ฌดํšจํ™”(Ignore) ํ”Œ๋ž˜๊ทธ ํ•˜๋‚˜๋งŒ์œผ๋กœ ๋น„๋™๊ธฐ ํ˜ธ์ถœ์ด ๊ผฌ์ธ ์‘๋‹ต์„ ๊น”๋”ํ•˜๊ฒŒ ๋ฌด์‹œํ•˜๊ณ  ๋ฐฉ์–ดํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“‹ ๋ชฉ์ฐจ


๐Ÿ“Œ ์ด ๋ฌธ์„œ๋ฅผ ์ฝ๊ธฐ ์ „์—

โฑ๏ธ ์˜ˆ์ƒ ์ฝ๊ธฐ ์‹œ๊ฐ„: 10๋ถ„ / ํ•ต์‹ฌ ํŒŒํŠธ: 6๋ถ„

๐Ÿ—บ๏ธ ์ด ๋ฌธ์„œ์˜ ๋ฐฐ๊ฒฝ ์„ธ๊ณ„๊ด€: '์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ'

  • ์˜์ˆ™(๋””์ž์ด๋„ˆ): "์˜์ฒ ์”จ! ์œ ์ € ํ”„๋กœํ•„ ์นด๋“œ์—์„œ '์ฒ ์ˆ˜'๋ฅผ ๋ˆŒ๋ €๋‹ค๊ฐ€ ๊ณง๋ฐ”๋กœ '์˜ํฌ'๋ฅผ ๋ˆŒ๋ €๋Š”๋ฐ... ํ™”๋ฉด์— ์˜ํฌ ์‚ฌ์ง„ ๋ฐ‘์— ์ฒ ์ˆ˜ ์ด๋ฆ„์ด ๋– ์š”! ๊ท€์‹  ๋“ค๋ฆฐ ๊ฑฐ ์•„๋‹ˆ์—์š”?"
  • ์˜ํ˜ธ(๋ฆฌ๋“œ): "๋””์ž์ด๋„ˆ๋‹˜, ๊ท€์‹ ์ด ์•„๋‹ˆ๋ผ ์˜์ฒ  ๋‹˜์˜ ์ฝ”๋“œ๊ฐ€ ๊ผฌ์ธ ๊ฒ๋‹ˆ๋‹ค. ๋น„๋™๊ธฐ ์š”์ฒญ๋“ค์—๊ฒŒ ๋ ˆ์ด์‹ฑ ์‹œํ•ฉ(Race Condition) ์„ ์‹œ์ผœ๋†“๊ณ  ๋’ท์ •๋ฆฌ๋ฅผ ์•ˆ ํ•ด์ฃผ๋ฉด ์ด๋Ÿฐ ๋Œ€์ฐธ์‚ฌ๊ฐ€ ๋‚˜์ฃ ."

๐Ÿค” ์™œ ์•Œ์•„์•ผ ํ•˜๋Š”๊ฐ€: ์Šน๋ฆฌํ•œ ์ž๊ฐ€ ์‚ด์•„๋‚จ๋Š” ๊ฒฝ์ฃผ (Race Condition)

์šฐ๋ฆฌ๊ฐ€ ํ‰์†Œ์— useEffect๋กœ API๋ฅผ ์ฐŒ๋ฅด๋ฉด, ๋ฆฌ์•กํŠธ ์•ˆ์—์„  ์ด๋ ‡๊ฒŒ ์ƒ๊ฐํ•˜๊ธฐ ๋งˆ๋ จ์ด์•ผ.
"1๋ฒˆ ์œ ์ € ๋ˆŒ๋ €์–ด -> 1๋ฒˆ ์‘๋‹ต ์™”๋„ค -> ๋ Œ๋”๋ง. ์ด์ œ 2๋ฒˆ ์œ ์ € ๋ˆŒ๋ €์–ด -> 2๋ฒˆ ์‘๋‹ต ์™”๋„ค -> ๋ Œ๋”๋ง."
์ˆœ์„œ๋Œ€๋กœ ๋”ฑ๋”ฑ ๋–จ์–ด์งˆ ๊ฒƒ ๊ฐ™์ง€? ํ˜„์‹ค์˜ ๋ชจ๋ฐ”์ผ ๋„คํŠธ์›Œํฌ ๋“ฑ ํ†ต์‹ ๋ง์€ ๊ทธ๋ ‡์ง€๊ฐ€ ์•Š์•„.

๐Ÿค” ์ž ๊น, ๋จผ์ € ์ƒ๊ฐํ•ด๋ด
์œ ์ €์˜ ์ธํ„ฐ๋„ท ํ™˜๊ฒฝ์ด 1๋ฒˆ ์š”์ฒญ์„ ๋ณด๋‚ผ ๋• 3G ๊ธ‰์œผ๋กœ ๋А๋ฆฌ๊ณ (๋Œ€์šฉ๋Ÿ‰ ์‚ฌ์ง„), 2๋ฒˆ ์š”์ฒญ์„ ๋ณด๋‚ผ ๋• 5G ๊ธ‰์œผ๋กœ ๋‚ ์•„๋‹ค๋…”์–ด(ํ…์ŠคํŠธ ์กฐ๊ธˆ). ์˜์ฒ ์ด๊ฐ€ ์ฒ ์ˆ˜(1)๋ฅผ ๋ˆŒ๋ €๋‹ค๊ฐ€ ๋น›์˜ ์†๋„๋กœ ์˜ํฌ(2)๋ฅผ ํด๋ฆญํ•˜๋ฉด ํ™”๋ฉด์€ ๋ˆ„๊ตฌ์˜ ์ •๋ณด๋กœ ๋ฎ์ผ๊นŒ?

โŒ ์˜์ฒ ์ด์˜ ๊ท€์‹ ๋“ค๋ฆฐ ํ”„๋กœํ•„ ์นด๋“œ ์ฝ”๋“œ

// โŒ ์ˆœ์ง„ํ•œ ๋น„๋™๊ธฐ ํ˜ธ์ถœ (Naive Approach)
function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
 
  useEffect(() => {
    // ๐Ÿ’ฅ ์ด API๋Š” ์ธํ„ฐ๋„ท ์†๋„์— ๋”ฐ๋ผ ์‘๋‹ต ๋„์ฐฉ ์ˆœ์„œ๊ฐ€ ๋’ค์ฃฝ๋ฐ•์ฃฝ์ผ ์ˆ˜ ์žˆ๋‹ค!
    let active = true; 
    fetchData(`/api/users/${userId}`).then(res => {
      // "๋„์ฐฉํ–ˆ์œผ๋‹ˆ๊นŒ ๋ฌด์กฐ๊ฑด setState ํ•ด์•ผ์ง€!" 
      setUser(res);
    });
  }, [userId]);
 
  if (!user) return <p>๋กœ๋”ฉ์ค‘...</p>;
  return <div>{user.name} ({userId})</div>;
}

์‚ฌ๊ฑด์˜ ๋ฐœ๋‹จ์€ ์ด๋Ÿฌํ•ฉ๋‹ˆ๋‹ค.

  1. ์‚ฌ์šฉ์ž๊ฐ€ ์ฒ ์ˆ˜(userId: 1) ๋ฅผ ํด๋ฆญ! -> 1๋ฒˆ ์„œ๋ฒ„ ํ†ต์‹  ์ถœ๋ฐœ (์—„์ฒญ๋‚œ ๊ณ ํ™”์งˆ ์‚ฌ์ง„ ๋•Œ๋ฌธ์— ๋กœ๋”ฉ 3์ดˆ ๋”œ๋ ˆ์ด).
  2. ์„ฑ๊ฒฉ ๊ธ‰ํ•œ ์‚ฌ์šฉ์ž๊ฐ€ ํ™”๋ฅผ ๋‚ด๋ฉฐ ๊ณง๋ฐ”๋กœ 1์ดˆ ๋’ค ์˜ํฌ(userId: 2) ๋ฅผ ํด๋ฆญ! -> 2๋ฒˆ ์„œ๋ฒ„ ํ†ต์‹  ์ถœ๋ฐœ (๋ฐ์ดํ„ฐ๊ฐ€ ๊ฐ€๋ฒผ์›Œ ๋ฐ”๋กœ ์š”์ฒญ ์™„๋ฃŒ).
  3. ์˜ํฌ(2๋ฒˆ) ์‘๋‹ต ๋„์ฐฉ ๐Ÿ‘‰ ํ™”๋ฉด ์ƒํƒœ๋ฅผ "์˜ํฌ"๋กœ ๊ฐฑ์‹ ! (setUser(์˜ํฌ))
  4. ๐Ÿ“Œ ๊ทธ๋Ÿฐ๋ฐ... ์•„๊นŒ ์ถœ๋ฐœํ–ˆ๋˜ ์ฒ ์ˆ˜(1๋ฒˆ)์˜ ์‘๋‹ต์ด ๋š๋ฐฐ๊ธฐ์— ๋ ‰์ด ๊ฑธ๋ ธ๋‹ค๊ฐ€ ์ด์ œ์•ผ(3์ดˆ ๋’ค์—) ํ—๋ ˆ๋ฒŒ๋–ก ๋„์ฐฉ! ๐Ÿ‘‰ "์˜ค, ๋‚˜๋„ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์™”์–ด!" ํ•˜๊ณ  ํ™”๋ฉด ์ƒํƒœ๋ฅผ ๋ฌด์ž๋น„ํ•˜๊ฒŒ "์ฒ ์ˆ˜"๋กœ ๋ฎ์–ด์”Œ์›€! (setUser(์ฒ ์ˆ˜))

์œ ์ €๋Š” ์˜ํฌ๋ฅผ ๋ˆ„๋ฅธ ์ƒํƒœ์ธ๋ฐ, ๋А์ง€๋ง‰์ด ์ง€๊ฐ ๋„์ฐฉํ•œ ์˜›๋‚  ๋ฐ์ดํ„ฐ(์ฒ ์ˆ˜)๊ฐ€ ํ™”๋ฉด์„ ๋ฎ์–ด๋ฒ„๋ฆฐ ๊ฑฐ์•ผ. ์ด๊ฒŒ ํ”„๋ก ํŠธ์—”๋“œ ๋น„๋™๊ธฐ์˜ ๊ฐ€์žฅ ๋”์ฐํ•œ ์ , **๊ฒฝ์Ÿ ์ƒํƒœ(Race Condition)**์•ผ.


๐Ÿ—๏ธ ๋น„์œ ๋กœ ๋จผ์ € ์ดํ•ดํ•˜๊ธฐ

๐Ÿง’ 5์‚ด์—๊ฒŒ ์„ค๋ช…ํ•œ๋‹ค๋ฉด?
์—„๋งˆ(๋ฆฌ์•กํŠธ)๊ฐ€ ํ”ผ์ž์ง‘์— ์ „ํ™”๋ฅผ ๊ฑธ์—ˆ์–ด. "์—ฌ๋ณด์„ธ์š”, ํŽ˜ํผ๋กœ๋‹ˆ ํ•œ ํŒ์ด์š”!"(1๋ฒˆ ์š”์ฒญ)
๊ทผ๋ฐ 5๋ถ„์ด ์ง€๋‚˜๋„ ๋ฐฐ๋‹ฌ์ด ์•ˆ ์™€์„œ ๋‹ต๋‹ตํ•ด์ง„ ์—„๋งˆ๊ฐ€ ์งœ์ฆ์„ ๋‚ด๋ฉฐ ๊ณง๋ฐ”๋กœ ๋‹ค๋ฅธ ํ”ผ์ž์ง‘์— ์ „ํ™”๋ฅผ ๊ฑธ์—ˆ์–ด. "์•„ํœด ์ทจ์†Œ์ทจ์†Œ, ๊ทธ๋ƒฅ ์น˜์ฆˆ ํ”ผ์ž ํ•˜๋‚˜์š”!"(2๋ฒˆ ์š”์ฒญ)
์ด์•Œ ๋ฐฐ์†ก์ธ ์น˜์ฆˆ ํ”ผ์ž๊ฐ€ ๋จผ์ € ๋„์ฐฉํ•ด์„œ ๋ง›์žˆ๊ฒŒ ๋จน๊ณ  ์žˆ๋Š”๋ฐ...(ํ–‰๋ณตํ•œ ํ™”๋ฉด)
๊ฐ‘์ž๊ธฐ ํ•œ ์‹œ๊ฐ„ ๋’ค์— ๋‹ค ์‹์–ด๋น ์ง„ ํŽ˜ํผ๋กœ๋‹ˆ ํ”ผ์ž ๋ฐฐ๋‹ฌ์›์ด ๋ฌธ์„ ์พ…์พ… ๋‘๋“œ๋ฆฌ๋ฉฐ ๋ฌด์ž‘์ • ์น˜์ฆˆ ํ”ผ์ž๋ฅผ ๋นผ์•—๊ณ  ๊ทธ๊ฑธ ์‹ํƒ ์œ„์— ์˜ฌ๋ ค๋ฒ„๋ ค!
"์–ด? ์ด๊ฑด ์šฐ๋ฆฌ๊ฐ€ ์ง€๊ธˆ ์›ํ•˜๋Š” ํ”ผ์ž๊ฐ€ ์•„๋‹Œ๋ฐ์š”?!" ๋ฐ˜ํ•ญ๋„ ๋ชปํ•˜๊ณ  ์‹ํƒ(ํ™”๋ฉด)์ด ์ ๋ น๋‹นํ•˜์ง€.

๋ถ€๋ชจ๋‹˜(๊ฒฝํ—˜ ๋งŽ์€ ๊ฐœ๋ฐœ์ž)์€ ์ „ํ™”ํ•  ๋•Œ ์–ด๋–ป๊ฒŒ ํ• ๊นŒ? ์น˜์ฆˆ ํ”ผ์ž ์‹œ์ผฐ์„ ๋•Œ, ์ด์ „์— ๋ถˆ๋ €๋˜ ํŽ˜ํผ๋กœ๋‹ˆ ๋ฐฐ๋‹ฌ์›์„ ํ–ฅํ•ด **"์•ผ!! ์šฐ๋ฆฌ ๋ฐฉ๊ธˆ ์ทจ์†Œํ–ˆ์œผ๋‹ˆ๊นŒ ๋„ˆ๋Š” ํ”ผ์ž ๋‚˜์™€๋„ ๊ฐ€์ ธ์˜ค์ง€ ๋ง๊ณ  ๋ฌด์‹œํ•ด(Ignore) ๋Œ์•„๊ฐ€!"**๋ผ๊ณ  ์ฒ ์ €ํ•˜๊ฒŒ ๋’ท์ •๋ฆฌ(Cleanup) ์ „ํ™”๋ฅผ ํ•œ ํ†ต ๋Œ๋ ธ๊ฒ ์ง€.

โœ… ํ•ต์‹ฌ ์›๋ฆฌ:
๋ฆฌ์•กํŠธ useEffect ์•ˆ์ชฝ์˜ return () => {} ์ฝ”๋“œ๋Š” ์œ ์ €๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋– ๋‚  ๋•Œ๋งŒ ์‹คํ–‰๋˜๋Š” ๊ฒŒ ์•„๋‹ˆ์•ผ.
์ƒํƒœ ์กฐ๊ฑด([userId])์ด ๋ฐ”๋€Œ์–ด์„œ ์ƒˆ๋กœ์šด ๋™๊ธฐํ™”(์ƒˆ๋กœ์šด Effect)๊ฐ€ ๋ฎ์–ด์”Œ์›Œ์ง€๊ธฐ ์ง์ „์—, ๋ฆฌ์•กํŠธ๋Š” ํ•ญ์ƒ ๋ฌด์กฐ๊ฑด ์ด ํด๋ฆฐ์—… ๋’ท์ •๋ฆฌ ์ฝ”๋“œ๋ฅผ ๋จผ์ € ์‹คํ–‰์‹œ์ผœ ์ค˜.
์ด ์ˆœ๊ฐ„์— "์•„๊นŒ ์ถœ๋ฐœํ–ˆ๋˜ ๋น„๋™๊ธฐ ์š”์ฒญ์˜ ๋ฌธ๋งฅ์€ ๋ฌด์‹œํ•ด๋ฒ„๋ ค๋ผ" ๋ผ๊ณ  ์„ ์–ธํ•ด ๋ฒ„๋ฆฌ๋ฉด ๋งŒ์‚ฌ ํ•ด๊ฒฐ!


๐Ÿงฉ ํด๋ฆฐ์—…(Cleanup): ํ”Œ๋ž˜๊ทธ ๊ธฐ๋ฒ•์˜ ์•„๋ฆ„๋‹ค์›€

์ด ๊ท€์‹  ๊ฐ™์€ ๋ ˆ์ด์Šค ์ปจ๋””์…˜์„ ๋ง‰๋Š” ๊ฐ€์žฅ ์›์ดˆ์ ์ด๋ฉด์„œ ๊ฐ€์žฅ ์™„๋ฒฝํ•œ 5๋…„ ์ฐจ์˜ ํŒจํ„ด์ด ์žˆ์–ด.
API ์ž์ฒด๋ฅผ ์ค‘๋‹จ(AbortController)์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•๋„ ํ›Œ๋ฅญํ•˜์ง€๋งŒ, ์ฝ”๋“œ ๋ธ”๋ก์„ ์ œ์–ดํ•˜๋Š” ๋‹จ์ˆœํ•œ boolean ๊นƒ๋ฐœ(ํ”Œ๋ž˜๊ทธ) ๊ธฐ๋ฒ•์ด ๊ฐ€๋…์„ฑ์ด ๊ทน๊ฐ•์ด์ง€.

โœ… ์˜ํ˜ธ์˜ ๋ฆฌํŒฉํ† ๋ง: ignore ๊นƒ๋ฐœ ํ”๋“ค๊ธฐ

// โœ… ๋ฐฉ์–ด์ ์ธ ๋™๊ธฐํ™” ์ฝ”๋“œ (Pro Approach)
function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
 
  useEffect(() => {
    // 1. ๋ฐฉ๊ธˆ ๋‚ด๊ฐ€ ํŒŒ๋†“์€ ์ด ์Šค๋ƒ…์ƒท ์„ธ๊ณ„๊ด€์—์„œ, ๋‚˜๋Š” ์œ ํšจํ•˜๋‹ค. (true)
    let ignore = false; 
 
    async function fetchProfile() {
      const res = await fetchData(`/api/users/${userId}`);
      
      // 3. ์„œ๋ฒ„ ์‘๋‹ต์ด ๋„์ฐฉํ–ˆ์„ ๋•Œ, ๋ˆ„๊ตฐ๊ฐ€ ๋ฐ–์—์„œ ๋‚˜๋ฅผ ๋ฌดํšจํ™”(true) 
      // ์‹œํ‚ค์ง€ ์•Š์•˜์„ ๋•Œ์—๋งŒ ํ™”๋ฉด์— ๋ฎ์–ด์”Œ์šฐ๋Š” ๊ฑธ ํ—ˆ๋ฝํ•œ๋‹ค!
      if (!ignore) {
        setUser(res);
      }
    }
    
    fetchProfile(); // ๐Ÿ’ฅ ์ถœ๋ฐœ!
 
    // 2. ํ•˜์ง€๋งŒ userId๊ฐ€ 1์—์„œ 2๋กœ ๋ฐ”๋€Œ๊ฑฐ๋‚˜ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๊บผ์ง€๋Š” ๋“ฑ,
    // "๊ณผ๊ฑฐ์˜ ๋™๊ธฐํ™” ์Šค๋ƒ…์ƒท ์„ธ๊ณ„๊ด€"์ด ๋ถ€์„œ์ง€๋Š” ์ˆœ๊ฐ„ ์ด ์ฒญ์†Œ๋ถ€(Cleanup)๊ฐ€ ์ถœ๋™ํ•ฉ๋‹ˆ๋‹ค.
    return () => {
      ignore = true; // "์–ด์ด! ์•„๊นŒ ๋– ๋‚œ ํŽ˜ํผ๋กœ๋‹ˆ ๋ฐฐ๋‹ฌ์›! ๋„ˆ ๋Œ์•„์˜ฌ ๋•Œ ๋ฌด์‹œ์ฒ˜๋ฆฌํ• ๊ฑฐ๋‹ˆ๊นŒ ๋‹ค ์‹์€ ๊ฑฐ ์„ธํŒ…ํ•˜์ง€ ๋งˆ!"
    };
  }, [userId]); // ๊ธฐ์ค€: userId
 
  if (!user) return <p>๋กœ๋”ฉ์ค‘...</p>;
  return <div>{user.name} ({userId})</div>;
}

์ด์ œ ์ฒ ์ˆ˜(1)๋ฅผ ๋ˆ„๋ฅด๊ณ  ๋น›์˜ ์†๋„๋กœ ์˜ํฌ(2)๋ฅผ ํด๋ฆญํ•˜๋Š” ์ˆœ๊ฐ„์˜ ํ๋ฆ„์„ ์ชผ๊ฐœ๋ณผ๊ฒŒ.

  1. ์ฒ ์ˆ˜(1) ๋ Œ๋”๋ง -> ignore1 = false ์„ ์–ธ. ์„œ๋ฒ„ ์ถœ๋ฐœ! (3์ดˆ ๊ฑธ๋ฆผ)
  2. ์˜ํฌ(2) ํด๋ฆญ -> ๋ฆฌ์•กํŠธ: "์–ด? ๊ทœ์น™์ด ์˜ํฌ๋กœ ๋ฐ”๋€Œ์—ˆ๋„ค! ์ž ๊น, ๊ทธ์ „์— ์ฒ ์ˆ˜ ๋•Œ ๋‚จ๊ฒจ๋‘” ์ฐŒ๊บผ๊ธฐ๋ถ€ํ„ฐ ํด๋ฆฐ์—…(์ฒญ์†Œ)ํ•œ๋‹ค!"
  3. ์ฒ ์ˆ˜์˜ ํด๋ฆฐ์—… ๋ฐœ๋™! ๐Ÿ‘‰ ignore1 = true๋กœ ๋ณ€๊ฒฝ๋จ. (์ฒ ์ˆ˜ ๋ฐฐ๋‹ฌ์› ๋ฌดํšจํ™”!!)
  4. ์˜ํฌ(2) ๋ Œ๋”๋ง -> ignore2 = false ์„ ์–ธ. ์„œ๋ฒ„ ์ถœ๋ฐœ! (1์ดˆ ๊ฑธ๋ฆผ, ๋จผ์ € ๋„์ฐฉ, ํ™”๋ฉด์— ์˜ํฌ ์„ธํŒ…)
  5. ๋“œ๋””์–ด ์ฒ ์ˆ˜(1) 3์ดˆ ๋’ค ์ง€๊ฐ ๋„์ฐฉ. ํ•˜์ง€๋งŒ if (!ignore) ๋ฃธ์— ๋“ค์–ด๊ฐ€๋ ค๋Š” ์ฐฐ๋‚˜, ์ด ๊ณผ๊ฑฐ์˜ ๊ฐ์˜ฅ์— ๊ฐ‡ํžŒ ์ฒ ์ˆ˜ ์„ธ๊ณ„๊ด€์˜ ignore1 ์€ ์ด๋ฏธ 2๋ฒˆ ์Šคํ…์—์„œ true ๋กœ ๋ฐ”๋€Œ์–ด ์žˆ์ง€!
  6. "์•„... ๋ฌด์‹œ๋‹นํ–ˆ๊ตฐ." (์ƒํƒœ ์—…๋ฐ์ดํŠธ ๋ฌด์‚ฐ, ์•ˆ์ „๋นต ์œ ์ง€ โœ…)

์ด๊ฒƒ์ด ๋ฆฌ์•กํŠธ ๋””์ž์ธ ์ฒ ํ•™์ด ์„ ์‚ฌํ•˜๋Š” ๊ฐ€์žฅ ์ง๊ด€์ ์ด๊ณ  ์™„๋ฒฝํ•œ ์˜›๋‚  ๋ฐ์ดํ„ฐ ๋ฐฉ์–ด ๊ธฐ๋‘ฅ์ด์•ผ.


๐Ÿ’ฅ ์—๋Ÿฌ ํ•ด๊ฒฐ ์นดํƒˆ๋กœ๊ทธ

โŒ Cleanup์„ ์“ฐ์ง€ ์•Š์€ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋ฒ„๊ทธ(Memory Leak)

์–ธ์ œ ๋‚˜์˜ค๋Š”๊ฐ€?

# ๊ฐœ๋ฐœ์ž ๋„๊ตฌ ์ฝ˜์†”์˜ ๋นจ๊ฐ„ ๊ฒฝ๊ณ ์ฐฝ
Warning: Can't perform a React state update on an unmounted component. 
This is a no-op, but it indicates a memory leak in your application. 
To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

**์›์ธ:**๋ชจ๋‹ฌ์ฐฝ ์•ˆ์—์„œ 10์ดˆ์งœ๋ฆฌ API ํ†ต์‹ ์„ ๋‚ ๋ ธ์–ด. ๊ทผ๋ฐ ์œ ์ €๊ฐ€ 2์ดˆ ๋งŒ์— [X] ๋ฒ„ํŠผ์„ ๋‹ซ์•„๋ฒ„๋ ค์„œ ๋ชจ๋‹ฌ ์ปดํฌ๋„ŒํŠธ ์ „์ฒด๊ฐ€ ํญํŒŒ(Unmount)๋์–ด!
๊ทธ๋Ÿฐ๋ฐ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ๋Š” 10์ดˆ ๋’ค์— API ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฌด์‚ฌํžˆ ์„œ๋ฒ„์—์„œ ๋–จ์–ด์ ธ ๋Œ์•„์™”๊ณ , ์ฃฝ์–ด ์—†์–ด์ง„ ๋ฌด๋ค(๋ชจ๋‹ฌ์ฐฝ์˜ setState)์— ๋Œ€๊ณ  ์‚ฟ๋Œ€์งˆ์„ ํ•˜๋ฉฐ ์ƒํƒœ๋ฅผ ๋ฐ”๊พธ๋ ค๊ณ  ํ•˜๋‹ˆ๊นŒ ๋ฆฌ์•กํŠธ๊ฐ€ ๊ธฐ๊ฒ์„ ํ•˜๋ฉด์„œ "์•„, ์ด๋ฏธ ์ฃฝ์€ ์•  ์žก๊ณ  ํ”๋“ค์ง€ ๋งˆ! ๋ฉ”๋ชจ๋ฆฌ ๋ฐ•์‚ด ๋‚ฌ์–ด!" ๋ผ๊ณ  ๋ถ‰์€ ๊ฒฝ๊ณ ์ฐฝ์„ ์•„์šฐ์„ฑ์น˜๋Š” ๊ฑฐ์•ผ.

ํ•ด๊ฒฐ์ฑ…:
๋ณธ ๊ฐ€์ด๋“œ์˜ ์˜ํ˜ธ๊ฐ€ ์ง  ์ฝ”๋“œ์ฒ˜๋Ÿผ return () => { ignore = true; } ๋ฅผ ๊ผฌ๋ฐ•๊ผฌ๋ฐ• ์ถ”๊ฐ€ํ•ด! ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํญํŒŒ๋  ๋•Œ ํด๋ฆฐ์—…์ด ์šฐ์„  ๋ฐœ๋™๋˜์–ด ignore ๋ฅผ ๋ฐ”๊พธ๋‹ˆ๊นŒ, ๋ง๋ น์ด ๋˜๋Œ์•„์™€๋„ ์•ˆ์ „ํ•˜๊ฒŒ ๋ฌด์‹œ๋ผ. (์ฐธ๊ณ : React 18+ ๋ฒ„์ „์—์„  StrictMode ๋“ฑ์ด ๊ฐœ์„ ๋˜์–ด ๊ฒฝ๊ณ ๊ฐ€ ๋œ ๋‚˜์˜ค๊ธด ํ•˜์ง€๋งŒ, ์•ˆ์ „ ์„ค๊ณ„์˜ ๊ทผ๊ฐ„์€ ๋™์ผํ•ด)


๐Ÿ ์ด๋ฒˆ์— ๋ฐฐ์šด ๋‚ด์šฉ ์ด์ •๋ฆฌ

์ƒํ™ฉโŒ ๋‚˜์œ ๋ฉ˜ํƒˆ (๋ฐฉ๊ด€)โœ… ํ”„๋กœ์˜ ๋ฉ˜ํƒˆ (ํ†ต์ œ/๋ฌด์‹œ)
์—ฐ์† ํด๋ฆญ ๋น„๋™๊ธฐ ์ƒํ™ฉ"์„ ์ฐฉ์ˆœ ๋„์ฐฉ์ˆœ์œผ๋กœ ํ™”๋ฉด ๋ฐ€์–ด๋‚ผ ๊ฑด๋ฐ ์•Œ์•„์„œ ๋˜๊ฒ ์ง€""์ตœ์‹  ํด๋ฆญ(ID) ์‘๋‹ต ์Šค๋ƒ…์ƒท๋งŒ ์‚ด๋ ค๋‘๊ณ  ์•„๊นŒ ์ถœ๋ฐœํ•œ ์ข€๋น„ ํ†ต์‹ ์› ๋ฐ์ดํ„ฐ๋Š” ignore ๊นƒ๋ฐœ๋กœ ์ปท์•„์›ƒ(Cut-out) ์‹œํ‚จ๋‹ค"

๐Ÿ’ก ํ•œ ์ค„๋กœ ๊ธฐ์–ตํ•˜๊ธฐ
๋น„๋™๊ธฐ useEffect์—์„œ return () => { ์น˜์šฐ๊ธฐ }๋ฅผ ๋นผ๋จน๋Š” ๊ฒƒ์€, ํ™”์žฅ์‹ค์„ ์‚ฌ์šฉํ•˜๊ณ  ๋ณ€๊ธฐ ๋ฌผ์„ ๋‚ด๋ฆฌ์ง€ ์•Š๋Š” ์ง“๊ณผ ์™„๋ฒฝํ•˜๊ฒŒ ๋™์ผํ•œ ์ธํ”„๋ผ ํƒ€๋ฝ ํ–‰์œ„๋‹ค.


๐Ÿฃ ์˜์ฒ ์ด์˜ ํ‡ด๊ทผ ์ผ๊ธฐ

์˜ˆ์ „์— ์ฝ˜์†”์— ๋นจ๊ฐ„์ƒ‰์œผ๋กœ '์ฃฝ์€ ์ปดํฌ๋„ŒํŠธ์— setState ํ•˜์ง€ ๋งˆ!' ๊ฒฝ๊ณ  ๋–ด์„ ๋•Œ ๋ญ” ์†Œ๋ฆฐ์ง€ ๋ชฐ๋ผ์„œ ๋ฌด์‹œํ–ˆ์—ˆ๋Š”๋ฐ... ํ”ผ์ž ๋ฐฐ๋‹ฌ ๋น„์œ ๋ฅผ ๋“ฃ์ž๋งˆ์ž ๋‚ด๊ฐ€ ๋‚ด ์ฝ”๋“œํ•œํ…Œ ๋ฌด์Šจ ํญ๋ ฅ์„ ์ €์งˆ๋ €๋Š”์ง€ ๋ช…ํ™•ํ•ด์กŒ๋‹ค. Race Condition์ด๋ผ๋Š” ์šฉ์–ด๋„ ์ด์ œ ์™„๋ฒฝํžˆ ์ฐฐ๋–ก๊ฐ™์ด ์ดํ•ด๊ฐ„๋‹ค.

๐Ÿ’ก "๋น„๋™๊ธฐ ๊ฒฝ์ฃผ(Race Condition)๋ฅผ ์กฐ์‹ฌํ•˜๋ผ! ๋น ๋ฅธ ํด๋ฆญ์œผ๋กœ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ดํƒˆํ•  ๋• Cleanup์—์„œ ignore ํ”Œ๋ž˜๊ทธ ํ•˜๋‚˜๋งŒ ๊ฝ‚์•„์ฃผ๋ฉด ์™„๋ฒฝ ๋ฐฉ์–ด๊ฐ€ ๋œ๋‹ค."

์˜์ˆ™ ๋””์ž์ด๋„ˆ๋‹˜์ด ๊ท€์‹  ๋“ค๋ฆฐ ํ™”๋ฉด ์ข€๋น„ ๊ฐ™๋‹ค๊ณ  ํ–ˆ์„ ๋•Œ ์ฐ”๋”ํ–ˆ๋Š”๋ฐ, ์ด์ œ ๋” ์šฐ์•„ํ•˜๊ณ  ํŠผํŠผํ•œ ๋ฐฉ์–ด๋ง‰์„ ์น  ์ˆ˜ ์žˆ๊ฒŒ ๋๋‹ค. ํด๋ฆฐ์—… ์•ˆ ํ•˜๋Š” ๊ฒŒ ๋ณ€๊ธฐ ๋ฌผ ์•ˆ ๋‚ด๋ฆฌ๋Š” ๊ฑฐ๋ž‘ ๋˜‘๊ฐ™๋‹ค๋‹ˆ... ์˜ํ˜ธ ๋‹˜ ํŒฉํญ ๋•๋ถ„์— ์˜ค๋Š˜ ๋‚ด ์ฝ”๋“œ๊ฐ€ ํ›จ์”ฌ ์œ„์ƒ์ ์œผ๋กœ ๋ณ€ํ–ˆ๋‹ค. ๊ธฐ๋ถ„ ์ข‹๊ฒŒ ํ‡ด๊ทผ! ์ง€ํ•˜์ฒ ์—์„œ AbortController ํ•œ๋ฒˆ ํ›‘์–ด๋ณด๊ณ  ๊ฐ€์•ผ์ง€.


๐Ÿ“ ๋งˆ๋ฌด๋ฆฌ ํ€ด์ฆˆ

Q1. useEffect์˜ Cleanup(๋ฐ˜ํ™˜ ํ•จ์ˆ˜) ์ฝ”๋“œ๊ฐ€ ์ •ํ™•ํžˆ ๋ฐœ๋™๋˜๋Š” ๋‘ ๊ฐ€์ง€ ์ˆœ๊ฐ„(Timing)์„ ๊ฐ€์žฅ ์ž˜ ์„œ์ˆ ํ•œ ๊ฒƒ์€?

  • A) ์˜ค์ง ๋ธŒ๋ผ์šฐ์ € ์ฐฝ(ํƒญ)์„ ์™„์ „ํžˆ ์ข…๋ฃŒํ•  ๋•Œ๋งŒ / ์‚ฌ์šฉ์ž๊ฐ€ ์ƒˆ๋กœ๊ณ ์นจ ํ‚ค๋ฅผ ๋ˆ„๋ฅผ ๋•Œ.
  • B) ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ตœ์ดˆ ํ™”๋ฉด์— ๋ ์›Œ์งˆ ๋•Œ / ์ปดํฌ๋„ŒํŠธ ์•ˆ์— ์žˆ๋Š” ์ผ๋ฐ˜ ํด๋ฆญ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ.
  • C) ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ™”๋ฉด์—์„œ ์™„์ „ํžˆ ์‚ฌ๋ผ์งˆ(Unmount) ๋•Œ / ๊ทธ๋ฆฌ๊ณ ! ๋‹ค์Œ ๋ Œ๋”๋ง ์‚ฌ์ดํด์— ์˜ํ•ด ํ•ด๋‹น Effect๊ฐ€ ๋‹ค์‹œ ํŠธ๋ฆฌ๊ฑฐ(์žฌ์‹คํ–‰) ๋˜๊ธฐ ์ง์ „.
  • D) ์‚ฌ์šฉ์ž๊ฐ€ ์ฝ˜์†” ๋กœ๊ทธ๋ฅผ ๊ฐ์‹œํ•˜๊ณ  ์žˆ์„ ๋•Œ / ๊ฐ•์ œ๋กœ React Garbage Collection์„ ํ˜ธ์ถœํ•  ๋•Œ.

โœ… ์ •๋‹ต: C

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค: ์ด๊ฒŒ Cleanup์˜ ์น˜ํŠธํ‚ค ์›๋ฆฌ์ž…๋‹ˆ๋‹ค. ๋‹จ์ˆœํžˆ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฃฝ์„ ๋•Œ(Unmount) ๋งŒ ๋’ท์ •๋ฆฌ๋ฅผ ํ•˜๋Š” ๊ฒŒ ์•„๋‹™๋‹ˆ๋‹ค! ์‚ฌ์šฉ์ž๊ฐ€ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ์ƒํƒœ ๊ฐ’์ด ๋ฐ”๋€Œ์–ด [userId] ์˜์กด์„ฑ์ด ๋‹ฌ๋ผ์ง€๋ฉด, ๋ฆฌ์•กํŠธ๋Š” ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋กœ ๋™๊ธฐํ™”๋ฅผ ์‹œํ‚ค๊ธฐ ์œ„ํ•ด ๋ฐ˜๋“œ์‹œ ๊ณผ๊ฑฐ์˜ ์Šค๋ƒ…์ƒท ํ”์ ์„ ์”ป์–ด๋‚ด๋Š” Cleanup ๋ถ€ํ„ฐ ๋จผ์ € ํ•œ ๋ฒˆ ์‹คํ–‰ ํ•œ ๋’ค, ๊ทธ์ œ์•ผ ์ƒˆ๋กœ์šด Effect ๋ณธ๋ฌธ์„ ๋Œ๋ฆฝ๋‹ˆ๋‹ค. ์ด ์›๋ฆฌ ๋•Œ๋ฌธ์— ๋ณ€์ˆ˜๋ฅผ ignore = true ๋กœ ๋ฐ”๊ฟ”์„œ ์ด์ „ ์š”์ฒญ์„ ํ๊ธฐ์‹œํ‚ค๋Š” ํ”Œ๋ž˜๊ทธ ๊ธฐ๋ฒ•์ด ์šฐ์•„ํ•˜๊ฒŒ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค!

Q2. ๋‹ค์Œ ์ค‘ Race Condition(๋น„๋™๊ธฐ ๊ฒฝ์Ÿ ์ฐธ์‚ฌ)์ด ๊ฐ€์žฅ ์‹ฌํ•˜๊ฒŒ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ทจ์•ฝํ•œ ์กฐ๊ฑด์„ ๊ฐ–์ถ˜ UI ์ƒํ™ฉ์€ ์–ด๋–ค ๊ฒƒ์ธ๊ฐ€์š”?

  • A) ์œ ์ €๊ฐ€ ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ์ƒํ’ˆ ์‚ญ์ œ ๋ฒ„ํŠผ์„ ํ•œ ๋ฒˆ ํด๋ฆญํ•œ ๋’ค ํ™”๋ฉด์ด ๋ฐ”๋กœ ๋กœ๋”ฉ(Spinning) ์Šคํฌ๋ฆฐ์œผ๋กœ ์ž ๊ธฐ๋Š” ํ™”๋ฉด.
  • B) ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ดˆ๋‹น 5๊ฐœ์”ฉ ๋ฐ”๋€Œ๋Š” "๊ด€์‹ฌ ์ฃผ์‹ ์ข…๋ชฉ(ํƒญ)" ๋ฆฌ์ŠคํŠธ๋ฅผ ๋„˜๋‚˜๋“ค๋ฉฐ ์ข…๋ชฉ์˜ ์ฐจํŠธ ๊ทธ๋ž˜ํ”„ ๋ฐ์ดํ„ฐ๋ฅผ API๋กœ ์ด์„œ ๊ทธ๋ ค์ฃผ๋Š” ํ™”๋ฉด.
  • C) ์ฒ˜์Œ์— ๋”ฑ ํ•œ ๋ฒˆ 50MB์งœ๋ฆฌ ํ†ต๊ณ„ ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€์ ธ์™€ ํ™”๋ฉด ์ค‘์•™์— ๋ฐ•์•„๋ฒ„๋ฆฌ๋Š” ๋ฉ”์ธ ํŽ˜์ด์ง€ ํ™”๋ฉด.
  • D) ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๋‚ด๋ถ€ State ์ˆซ์ž๋งŒ count + 1 ํ•˜๋„๋ก ์กฐ์ž‘๋œ ํ…์ŠคํŠธ ์นด์šดํ„ฐ ํƒ€์ด๋จธ ํ™”๋ฉด.

โœ… ์ •๋‹ต: B

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค: ํƒญ ์ „ํ™˜์ด๋‚˜ ์‹ค์‹œ๊ฐ„ ํƒ€์ดํ•‘(์ž๋™์™„์„ฑ ๊ฒ€์ƒ‰ UI)์ฒ˜๋Ÿผ ์‚ฌ์šฉ์ž๊ฐ€ ์—„์ฒญ๋‚˜๊ฒŒ ๋น ๋ฅธ ์†๋„๋กœ ํ‚ค ์ž…๋ ฅ์ด๋‚˜ ํƒญ ํด๋ฆญ์˜ ์กฐ๊ฑด์„ ๊ณ„์† ๋ณ€ํ™˜์‹œํ‚ฌ ๋•Œ, ๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ๋“ค์ด ์ „๋ถ€ ๋„คํŠธ์›Œํฌ ์ง€์—ฐ(Latency)์ด ๋™๋ฐ˜๋˜๋Š” ๋ฌด๊ฑฐ์šด ์„œ๋ฒ„ API ์š”์ฒญ์ผ ๋•Œ ์–ด๋งˆ์–ด๋งˆํ•œ ๋น„๋™๊ธฐ ์ง€์˜ฅ์˜ ๋ ˆ์ด์Šค ์ปจ๋””์…˜๋“ค์ด ์—ฐ์ถœ๋ฉ๋‹ˆ๋‹ค. 2๋ฒˆ ํƒญ์˜ ์„œ๋ฒ„์š”์ฒญ์€ ๋ฒˆ๊ฐœ์ฒ˜๋Ÿผ ์™”๋Š”๋ฐ, ์•„๊นŒ ๋ˆ„๋ฅธ 1๋ฒˆ ํƒญ์˜ ์ˆ˜์‹ญ MB ์ด๋ฏธ์ง€๊ฐ€ 5์ดˆ ๋’ค์— ๋ฉ์ฒญํ•˜๊ฒŒ ํ™”๋ฉด์„ ์พ… ๋ฎ์–ด๋ฒ„๋ฆฌ๋‹ˆ๊นŒ์š”! Cleanup ๋ฌดํšจํ™” ์ฒ˜๋ฆฌ๊ฐ€ ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•œ ๊ณณ์ž…๋‹ˆ๋‹ค.

Q3. useEffect ์™ธ๋ถ€ ํ†ต์‹ ์„ ์บ”์Šฌํ•˜๋Š” ๋” ๊ฐ•๋ ฅํ•œ ๋ฌด๊ธฐ์ธ ๋ธŒ๋ผ์šฐ์ € ๋‚ด์žฅ API AbortController ์— ๋Œ€ํ•ด ๋“ค์–ด๋ณธ ์ ์ด ์žˆ์„ ๊ฒ๋‹ˆ๋‹ค. ์ด API๋ฅผ ์ด์šฉํ•œ ํด๋ฆฐ์—… ์‹œ๋‚˜๋ฆฌ์˜ค์™€, ์˜ํ˜ธ๊ฐ€ ์“ด ๋นˆ ๋ณ€์ˆ˜(ํ”Œ๋ž˜๊ทธ) let ignore = false ํŠธ๋ฆญ ๊ฐ„์˜ ์‹ค์งˆ์  ์„ฑ๋Šฅ(๋„คํŠธ์›Œํฌ ๋ ˆ๋ฒจ) ์ฐจ์ด๋Š” ๋ฌด์—‡์ผ๊นŒ์š”? ์ฃผ๊ด€์‹์œผ๋กœ ๊ฐ„๋žตํžˆ ํ†ต์ฐฐ์„ ์จ๋ณด์„ธ์š”.

โœ… ์ •๋‹ต ๋ฐ ์ฃผ๊ด€์‹ ํ•ด์„ค:

์ฃผ๊ด€์‹ ํ•ด์„ค ์›๋ฆฌ:
๊ฐ€์žฅ ํฐ ์ฐจ์ด๋Š” ๋ง์ด ์†Œ๋ชจ๋˜๋Š” ์ž์›์˜ ์ค‘๋‹จ(Cancel) ์—ฌ๋ถ€์ž…๋‹ˆ๋‹ค. ์˜ํ˜ธ๊ฐ€ ๊ฐ€๋ฅด์ณ์ค€ let ignore = false ๋ณ€์ˆ˜ ํŠธ๋ฆญ์€ ์ฝ”๋“œ๊ฐ€ ์งœ๊ธฐ ์‰ฝ๊ณ  ๋ฌด๋‚œํ•˜๊ฒŒ ์“ธ ์ˆœ ์žˆ์ง€๋งŒ, ์ผ๋‹จ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ฒซ ํŽ˜ํผ๋กœ๋‹ˆ ๋ฐฐ๋‹ฌ์›์„ ์ถœ๋ฐœ์‹œ์ผฐ๋‹ค๋ฉด ๋ฐฐ๋‹ฌ์› ์ž์ฒด์˜ ํŠธ๋ž˜ํ”ฝ ์ด๋™(์„œ๋ฒ„ ๋ฐ์ดํ„ฐ ๋‹ค์šด๋กœ๋“œ)์„ ๋ง‰์ง€๋Š” ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๊ทธ์ € ๋ฐ์ดํ„ฐ ํ†ต์‹ ์ด ๋๋‚˜์„œ ์ง‘์— ๋„๋‹ฌํ–ˆ์„ ๋•Œ ์–์‚ฝํ•˜๊ฒŒ ๋ฌธ์„ ์•ˆ ์—ด์–ด์ฃผ๊ณ  ํ™”๋ฉด ์—…๋ฐ์ดํŠธ(setState)๋งŒ ๋ฌด์‹œํ•  ๋ฟ์ด์ฃ (์•ˆ์ „๋ง ํ™•๋ณด).
ํ•˜์ง€๋งŒ ๋ธŒ๋ผ์šฐ์ € ์ž์ฒด ์ง€์› API์ธ AbortController.abort() ๋ฅผ ํด๋ฆฐ์—…์— ๋ฌผ๋ ค ๊ตฌํ˜„ํ•˜๋ฉด? ๋ฆฌ์•กํŠธ๊ฐ€ ๋ฐฐ๋‹ฌ์›์ด ์ถœ๋ฐœํ•˜๊ณ  ์ค‘๊ฐ„์ฏค ์ง€๋‚ฌ์„ ๋•Œ "์•ผ! ๋ฐฐ์†ก ์ค‘์ง€ํ•ด ํ†ต์‹ ์„  ๋Š์–ด๋ฒ„๋ ค(Network Cancel)!" ๋ช…๋ น์„ ๋ธŒ๋ผ์šฐ์ € ๋ง์—๋‹ค ๊ฝ‚์•„๋ฒ„๋ฆฝ๋‹ˆ๋‹ค. ํฌ๋กฌ ๋„คํŠธ์›Œํฌ ํƒญ์— ๋นจ๊ฐ„์ƒ‰(canceled) ์—๋Ÿฌ ์ฐฝ์ด ์˜ˆ์˜๊ฒŒ ๋œจ๋ฉด์„œ, ๋ฐ์ดํ„ฐ ๋‚ญ๋น„ ํŠธ๋ž˜ํ”ฝ ์ž์ฒด๋ฅผ ์ค‘๊ฐ„์— ์†Œ๋ฉธ์‹œํ‚ค๋ฏ€๋กœ ์„ฑ๋Šฅ์ ์œผ๋กœ ๊ฐ€์žฅ ์ด์ƒ์ ์ธ ๋Œ€๊ธฐ์—… ๋งˆ์ธ๋“œ(๊ณ ์„ฑ๋Šฅ) ํ•ด๊ฒฐ์ฑ…์ด ์™„์„ฑ๋ฉ๋‹ˆ๋‹ค! (๋‘˜ ๋‹ค ๋ฌดํ•œ ๋ฐ์ดํ„ฐ ๋ฐฉ์–ด ํšจ๊ณผ๋Š” ๊ฐ™์Šต๋‹ˆ๋‹ค.)