๋ฐ˜์‘ํ˜•

์—„๊ฒฉ ๋ชจ๋“œ์˜ ๊ธฐ๋Šฅ


CRA๋กœ ์ƒ์„ฑํ•œ React ํ”„๋กœ์ ํŠธ์—์„  ์—„๊ฒฉ ๋ชจ๋“œ(Strict Mode)๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ ์šฉ๋ผ ์žˆ๋‹ค. ์—„๊ฒฉ ๋ชจ๋“œ๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ž ์žฌ์ ์ธ ๋ฌธ์ œ๋ฅผ ์•Œ์•„๋‚ด๊ธฐ ์œ„ํ•ด ๋ฆฌ์•กํŠธ์—์„œ ์ œ๊ณตํ•˜๋Š” ๋„๊ตฌ๋‹ค. ๊ฐœ๋ฐœ ๋ชจ๋“œ์—์„œ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง / API ํ˜ธ์ถœ ๋“ฑ์ด ์ค‘๋ณตํ•ด์„œ ๋ฐœ์ƒํ•œ๋‹ค๋ฉด ์—„๊ฒฉ ๋ชจ๋“œ ๋•Œ๋ฌธ์— ๊ทธ๋Ÿด ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋‹ค.

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./pages/App";

const root = ReactDOM.createRoot(
  document.getElementById("root") as HTMLElement,
);

root.render(<React.StrictMode>{/* ... */}</React.StrictMode>);

 

์—„๊ฒฉ ๋ชจ๋“œ๋Š” ์•„๋ž˜ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค. ์—„๊ฒฉ ๋ชจ๋“œ๋Š” ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ๋งŒ ์ ์šฉ๋˜๋ฉฐ UI์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š”๋‹ค(๋ Œ๋”๋ง X).

 

 

ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ ๋ฐ”๋””, ์ƒํƒœ ์—…๋ฐ์ดํŠธ ํ•จ์ˆ˜, useState, useMemo, useReducer ์ธ์ž์— ๋„˜๊น€ ํ•จ์ˆ˜ ๋“ฑ์„ 2๋ฒˆ์”ฉ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ๋„ ์—„๊ฒฉ ๋ชจ๋“œ์˜ ๊ธฐ๋Šฅ์ค‘ ํ•˜๋‚˜๋‹ค. ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๋„๋ก ์˜๋„์ ์œผ๋กœ 2๋ฒˆ์”ฉ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ.

 

๐Ÿ”๏ธ ์—„๊ฒฉ๋ชจ๋“œ๊ฐ€ ์˜๋„์ ์œผ๋กœ ์ค‘๋ณต ํ˜ธ์ถœํ•˜๋Š” ํ•จ์ˆ˜ ๋ชฉ๋ก

  • ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์˜ constructor, rendershouldComponentUpdate ๋ฉ”์„œ๋“œ
  • ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์˜ getDerivedStateFromProps static ๋ฉ”์„œ๋“œ
  • ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ ๋ฐ”๋””
  • State updater ํ•จ์ˆ˜ (setState์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ž)
  • useState, useMemo, useReducer์— ์ „๋‹ฌ๋˜๋Š” ํ•จ์ˆ˜

 

์ฒ˜์Œ์—” ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด ์™œ 2๋ฒˆ์”ฉ ํ˜ธ์ถœํ•ด์•ผ ํ•˜๋Š”์ง€ ์˜์•„ํ–ˆ๋‹ค. ์˜คํžˆ๋ ค ๋กœ๊ทธ๊ฐ€ ๋” ๋ณต์žกํ•ด์ ธ์„œ ๋ถˆํŽธํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ์—„๊ฒฉ ๋ชจ๋“œ ๋•๋ถ„์— ์ƒ๊ฐ์ง€ ๋ชปํ•œ ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌํ•œ ๋’ค๋ก  ๋˜๋ ค ์œ ์šฉํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ์ž˜ ์งœ์ธ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด๋ผ๋ฉด ๋™์ผํ•œ ์ž‘์—…์„ ์ค‘๋ณต ์ˆ˜ํ–‰ํ•˜๋”๋ผ๋„ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๊ฐ€ ์—†์–ด์•ผ ํ•œ๋‹ค.

 

์‚ฌ์ดํŠธ ์ดํŽ™ํŠธ ์‚ฌ๋ก€


์•„๋ž˜ ๊ธ€์“ฐ๊ธฐ ๊ธฐ๋Šฅ์„ ๋‹ด๋‹นํ•˜๋Š” Compose.tsx ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ๋‹ค. ์™„๋ฃŒ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ์ž‘์„ฑํ•œ ๊ธ€์„ ์ œ์ถœํ•˜๊ฑฐ๋‚˜, ๋‹ค๋ฅธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๋ฉด Compose ์ปดํฌ๋„ŒํŠธ๋Š” ์–ธ๋งˆ์šดํŠธ๋ผ์•ผ ํ•œ๋‹ค. ์ปดํฌ๋„ŒํŠธ๋ฅผ ์–ธ๋งˆ์šดํŠธํ•  ๋•Œ ์ž…๋ ฅ์ฐฝ์— ๋‚จ์•„์žˆ๋Š” ํ…์ŠคํŠธ๋ฅผ ๋ชจ๋‘ ์‚ญ์ œํ•˜๊ณ (clearDraft) ๋ฆฌ์ŠคํŠธ ํ™”๋ฉด์œผ๋กœ ์ด๋™ํ•˜๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” leavePage ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

// Compose.tsx
const leavePage = useCallback(() => {
  dispatch(clearDraft()); // ์ž…๋ ฅ์ฐฝ์— ๋‚จ์•„์žˆ๋Š” ํ…์ŠคํŠธ ์‚ญ์ œ
  navigate(siteUrl.community.list, { replace: true }); // ๋ฆฌ์ŠคํŠธ ํŽ˜์ด์ง€๋กœ ์ด๋™
}, [dispatch, navigate]);

const submitHandler = useCallback(async () => {
  try {
    await dispatch(submitDraft(draft)).unwrap(); // ์ž‘์„ฑํ•œ ๊ธ€ ์ œ์ถœ
    leavePage(); // ๊ธ€ ์ž‘์„ฑ์„ ๋งˆ์ณ์„œ ์–ธ๋งˆ์šดํŠธํ•˜๋Š” case
    // ...
  } catch (e) {
    // ...
  }
}, [dispatch, draft, navigate]);

useEffect(() => {
  return () => {
    leavePage(); // ๋’ค๋กœ๊ฐ€๊ธฐ ๋“ฑ ๋ผ์šฐํŠธ ๋ณ€๊ฒฝ์œผ๋กœ ์–ธ๋งˆ์šดํŠธํ•˜๋Š” case
  };
}, [leavePage]);

 

ํ•˜์ง€๋งŒ ์—„๊ฒฉ ๋ชจ๋“œ์—์„  Compose.tsx ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ •์ƒ์ ์œผ๋กœ ๋งˆ์šดํŠธ ํ•  ์ˆ˜ ์—†๋‹ค. useEffect๋ฅผ 2๋ฒˆ ์‹คํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. 2๋ฒˆ์งธ ์ดํŽ™ํŠธ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์ „ ํด๋ฆฐ์—… ํ•จ์ˆ˜์— ์žˆ๋Š” leavePage๋ฅผ ํ˜ธ์ถœํ•ด์„œ ๋ฆฌ์ŠคํŠธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•œ๋‹ค. ์ฆ‰, ๊ธ€์“ฐ๊ธฐ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜์ž๋งˆ์ž ๋ฆฌ์ŠคํŠธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

 

์ด ๋ฌธ์ œ๋Š” ์ž…๋ ฅ์ฐฝ ํ…์ŠคํŠธ ์‚ญ์ œ(clearDraft)์™€ ํŽ˜์ด์ง€ ์ด๋™ ๊ธฐ๋Šฅ์„ leavePage ํ•จ์ˆ˜์— ๋ชฐ์•„๋„ฃ๋Š”๋ฐ์„œ ๋น„๋กฏ๋๋‹ค. ๊ณฐ๊ณฐ์ด ์ƒ๊ฐํ•ด๋ณด๋ฉด leavePage ํ•จ์ˆ˜๋Š” clearDraft ์—ญํ• ๋งŒ ์ˆ˜ํ–‰ํ•˜๋ฉด ๋œ๋‹ค. leavePage ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ƒํ™ฉ์€ ๋ผ์šฐํŠธ ๋ณ€๊ฒฝ์œผ๋กœ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์–ธ๋งˆ์šดํŠธํ•˜๋Š” ์‹œ์ ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋ถˆํ•„์š”ํ•œ leavePage ํ•จ์ˆ˜๋ฅผ ์•„์˜ˆ ์—†์• ๋ฒ„๋ฆฌ๊ณ  ์•„๋ž˜์ฒ˜๋Ÿผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

// Compose.tsx
const submitHandler = useCallback(async () => {
  try {
    await dispatch(submitDraft(draft)).unwrap(); // ์ž‘์„ฑํ•œ ๊ธ€ ์ œ์ถœ
    navigate(siteUrl.community.list, { replace: true }); // ๋ฆฌ์ŠคํŠธ ํŽ˜์ด์ง€๋กœ ์ด๋™
    // ...
  } catch (e) {
    // ...
  }
}, [dispatch, draft, navigate]);

useEffect(() => {
  return () => {
    dispatch(clearDraft()); // ์ž…๋ ฅ์ฐฝ์— ๋‚จ์•„์žˆ๋Š” ํ…์ŠคํŠธ ์‚ญ์ œ
  };
}, [leavePage]);

 

์—„๊ฒฉ ๋ชจ๋“œ๋ฅผ ํ†ตํ•ด ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ 2๋ฒˆ์”ฉ ํ˜ธ์ถœํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ ์œ„ ๋ฒ„๊ทธ๋ฅผ ๋ฐœ๊ฒฌํ•˜์ง€ ๋ชปํ–ˆ์„ ๊ฒƒ์ด๋‹ค. ์—„๊ฒฉ ๋ชจ๋“œ๋Š” ์ƒ๊ฐ๋ณด๋‹ค ์œ ์šฉํ•˜๋‹ค.

 

๋ ˆํผ๋Ÿฐ์Šค


 

Strict ๋ชจ๋“œ – React

A JavaScript library for building user interfaces

ko.legacy.reactjs.org

 


๊ธ€ ์ˆ˜์ •์‚ฌํ•ญ์€ ๋…ธ์…˜ ํŽ˜์ด์ง€์— ๊ฐ€์žฅ ๋น ๋ฅด๊ฒŒ ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค. ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”
๋ฐ˜์‘ํ˜•