๐Ÿง  ์ฝ”๋“œ๊ฐ€ ๋„ˆ๋ฌด ๋น ๋ฅผ ๋•Œ๋งŒ ๋‚˜ํƒ€๋‚˜๋Š” React ๋ฒ„๊ทธ

๋ฐœํ–‰: (2026๋…„ 1์›” 2์ผ ์˜ค์ „ 03:07 GMT+9)
6 min read
์›๋ฌธ: Dev.to

Source: Dev.to

๐Ÿงฉ ๋ฌธ์ œ: โ€œ์™œ ๊ฐ ํ–‰์ด ์„œ๋กœ ๋‹ค๋ฅธ ์ƒํƒœ๋ฅผ ๋ณด๋Š”๊ฐ€?โ€

PrimeReactโ€ฏDataTable์— ๊ฐ ํ–‰๋งˆ๋‹ค ๋ฒ„ํŠผ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ถœ๋ ฅ์ด ๋‚˜ํƒ€๋‚ฌ์Šต๋‹ˆ๋‹ค:

Button 0 clicked โ†’ items.length = 1

ํด๋ฆญ ์‹œ์ ์˜ ์ „์—ญ ์ƒํƒœ์—๋Š” ๋ช…ํ™•ํžˆ 3๊ฐœ์˜ ์•„์ดํ…œ์ด ์žˆ์—ˆ์Œ์—๋„, ๊ฐ ๋ฒ„ํŠผ์€ ๋งˆ์น˜ ์ด์ „ ๋ฒ„์ „์˜ ์ƒํƒœ๋ฅผ ๊ธฐ์–ตํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋™์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ”ฌ ์ด์Šˆ ์žฌํ˜„ ๋ฐฉ๋ฒ•

  1. ํ…Œ์ด๋ธ”์— ํ–‰ 3๊ฐœ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.
  2. ํ–‰โ€ฏ1์˜ ๋ฒ„ํŠผ์„ ํด๋ฆญ โ†’ ๋กœ๊ทธโ€ฏ1.
  3. ํ–‰โ€ฏ2์˜ ๋ฒ„ํŠผ์„ ํด๋ฆญ โ†’ ๋กœ๊ทธโ€ฏ2.
  4. ํ–‰โ€ฏ3์˜ ๋ฒ„ํŠผ์„ ํด๋ฆญ โ†’ ๋กœ๊ทธโ€ฏ3.

๊ฐ ํ–‰์ด ๊ณผ๊ฑฐ์— โ€œ๊ณ ์ •โ€๋œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์˜€์Šต๋‹ˆ๋‹ค.

๐Ÿค” ์™œ ์ด๋ ‡๊ฒŒ ํ˜ผ๋ž€์Šค๋Ÿฌ์› ๋Š”๊ฐ€

  • UI๋Š” ์ •์ƒ์ ์œผ๋กœ ๋ณด์˜€๋‹ค.
  • ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋Š” ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ–ˆ๋‹ค.
  • ์˜ค๋ฅ˜๋‚˜ ๊ฒฝ๊ณ ๊ฐ€ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์•˜๋‹ค.
  • ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ๋„๋ฉด(cellMemo={false}) โ€œํ•ด๊ฒฐโ€๋˜๋Š” ๋“ฏํ–ˆ์œผ๋ฉฐ, ์ด๊ฒƒ์ด ๋‹จ์„œ๊ฐ€ ๋˜์—ˆ๋‹ค.

๐Ÿง  ์ˆจ๊ฒจ์ง„ ์›์ธ: ๋ฉ”๋ชจ์ด์ œ์ด์…˜ + ํด๋กœ์ €

PrimeReact์˜ DataTable์€ ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ์œ„ํ•ด ์…€ ๋ฉ”๋ชจ์ด์ œ์ด์…˜(cellMemo=true๊ฐ€ ๊ธฐ๋ณธ) ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ํŠน์ • ๋ฉ”๋ชจ ํ‚ค๊ฐ€ ๋ณ€ํ•  ๋•Œ๋งŒ ์…€์„ ๋‹ค์‹œ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.

์–ด๋””์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‚˜์š”?

  • ๊ธฐ์กด ํ–‰๋“ค์€ ๊ฐ™์€ ๊ฐ์ฒด ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์œ ์ง€ํ–ˆ๋‹ค.
  • ๋ฉ”๋ชจ์ด์ œ์ด์…˜๋œ ์…€์€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜์ง€ ์•Š์•˜๋‹ค.
  • ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ(onClick)๋Š” ์ƒ์„ฑ๋œ ๋ Œ๋” ์‹œ์ ์˜ ํด๋กœ์ €๋ฅผ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ–ˆ๋‹ค.

๊ฒฐ๊ณผ์ ์œผ๋กœ ๊ฐ ๋ฒ„ํŠผ์€ ์ƒ์„ฑ ์‹œ์ ์˜ ์ƒํƒœ ์Šค๋ƒ…์ƒท์„ ์บก์ฒ˜ํ–ˆ์œผ๋ฉฐโ€”๋ฉ”๋ชจ์ด์ œ์ด์…˜ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•œ ๊ณ ์ „์ ์ธ staleโ€‘closure ๋ฌธ์ œ์˜€์Šต๋‹ˆ๋‹ค. ์ƒํƒœ ๋กœ์ง ์ž์ฒด๊ฐ€ ์›์ธ์ด ์•„๋‹ˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๐Ÿงช ์ตœ์†Œ ์žฌํ˜„ ์˜ˆ์‹œ (Pure React)

import React from "react";

const Row = React.memo(
  ({ item, index, snapshotLength }) => {
    const onClick = () => {
      console.log(index, snapshotLength);
    };
    return Click;
  },
  (prev, next) => prev.item === next.item // โŒ snapshotLength ๋ฌด์‹œ
);

snapshotLength๊ฐ€ ๋ฉ”๋ชจ ๋น„๊ต์— ํฌํ•จ๋˜์ง€ ์•Š์•„ ํ–‰์ด ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜์ง€ ์•Š๊ณ , ํด๋ฆญ ํ•ธ๋“ค๋Ÿฌ๋Š” ์˜ค๋ž˜๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹คโ€”DataTable ๋ฒ„๊ทธ์™€ ๋™์ผํ•œ ์ƒํ™ฉ์ž…๋‹ˆ๋‹ค.

๐Ÿ› ๏ธ ์‹ค์ œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• (ํ•ดํ‚น์ด ์•„๋‹Œ)

๋น ๋ฅธ ์šฐํšŒ ๋ฐฉ๋ฒ•


๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ๋„๋ฉด ํฐ ํ…Œ์ด๋ธ”์—์„œ ์„ฑ๋Šฅ ์ด์ ์„ ์žƒ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์˜ฌ๋ฐ”๋ฅธ ํ•ด๊ฒฐ์ฑ…

PrimeReact์—์„œ๋Š” ํ–‰ ๊ตฌ์กฐ๊ฐ€ ๋ฐ”๋€” ๋•Œ๋งˆ๋‹ค ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ํ‚ค๊ฐ€ ๋ณ€ํ•˜๋„๋ก ์กฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

์ˆ˜์ • ์ „

cellMemoProps = { index };

์ˆ˜์ • ํ›„

cellMemoProps = { rowIndex };

rowIndex๋Š” ํ–‰์ด ์ถ”๊ฐ€, ์‚ญ์ œ, ์žฌ์ •๋ ฌ๋  ๋•Œ๋งˆ๋‹ค ๋ณ€ํ•˜๋ฏ€๋กœ, ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋ฉ”๋ชจ์ด์ œ์ด์…˜๋œ ์…€์„ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์„ฑ๋Šฅ์„ ํฌ์ƒํ•˜์ง€ ์•Š๊ณ ๋„ ์ตœ์‹  ํด๋กœ์ €๋ฅผ ํ™•๋ณดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

โœ… ๊ฒฐ๊ณผ

์ˆ˜์ •์„ ์ ์šฉํ•œ ๋’ค:

  • Buttonโ€ฏ0 โ†’ items.length = 3
  • Buttonโ€ฏ1 โ†’ items.length = 3
  • Buttonโ€ฏ2 โ†’ items.length = 3

staleโ€ฏclosure๊ฐ€ ์‚ฌ๋ผ์ง€๊ณ , ์„ฑ๋Šฅ ์ €ํ•˜๋„ ์—†์œผ๋ฉฐ, API ๋ณ€๊ฒฝ๋„ ํ•„์š”ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

๐Ÿคฏ ๋ถ€๊ฐ€ ์ธ์‚ฌ์ดํŠธ: useFieldArray๊ฐ€ โ€œ๊ทธ๋ƒฅ ์ž‘๋™ํ•œโ€ ์ด์œ 

React Hook Form์˜ useFieldArray๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ๋ฒ„๊ทธ๊ฐ€ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. useFieldArray๋Š” ์—…๋ฐ์ดํŠธ ์‹œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ๊ฐ์ฒด ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์ƒ์„ฑํ•˜๋ฏ€๋กœ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์ด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋ฌดํšจํ™”๋ฉ๋‹ˆ๋‹ค. ํ–‰์ด ์ž๋™์œผ๋กœ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜์ฃ โ€”๋งˆ๋ฒ•์ด ์•„๋‹ˆ๋ผ ๊ฐ์ฒด ์ •์ฒด์„ฑ์ด ์šฐ๋ฆฌ ํŽธ์œผ๋กœ ์ž‘์šฉํ•œ ๊ฒฐ๊ณผ์˜€์Šต๋‹ˆ๋‹ค.

๐Ÿง  ํ•ต์‹ฌ ์ •๋ฆฌ

  • ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ๋ฒ„๊ทธ๋Š” ์ •์ฒด์„ฑ(identity) ๋ฒ„๊ทธ์ด๋ฉฐ, ์ƒํƒœ ๋ฒ„๊ทธ๊ฐ€ ์•„๋‹ˆ๋‹ค.
  • ๋™์ž‘์— ์˜ํ–ฅ์„ ์ฃผ๋Š” ๋ชจ๋“  prop์€ ๋ฉ”๋ชจ ๋ฌดํšจํ™” ํ‚ค์— ํฌํ•จ์‹œ์ผœ์•ผ ํ•œ๋‹ค.
  • ์ƒํƒœ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๋”๋ผ๋„ staleโ€ฏclosure๊ฐ€ ์กด์žฌํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ๋„๋Š” ๊ฒƒ์€ ์ž„์‹œ ๋ฐฉํŽธ์ผ ๋ฟ, ๊ทผ๋ณธ์ ์ธ ํ•ด๊ฒฐ์ฑ…์ด ์•„๋‹ˆ๋‹ค.
  • ์„ฑ๋Šฅ ์ตœ์ ํ™”์—๋Š” ์ถ”๊ฐ€์ ์ธ ์ •ํ™•์„ฑ ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

๐Ÿš€ ๋งˆ๋ฌด๋ฆฌ ์ƒ๊ฐ

์ด ๋ฒ„๊ทธ๋Š”:

  • ๋ถˆ๊ฐ€๋Šฅํ•ด ๋ณด์˜€๋‹ค.
  • ๋กœ๊ทธ๋ฅผ ๋‚จ๊ฒจ๋„ ์‚ฌ๋ผ์กŒ๋‹ค.
  • โ€œ๋‹จ์ˆœํ™”โ€ํ•˜๋ฉด ์‚ฌ๋ผ์กŒ๋‹ค.

๋ Œ๋” ์Šค๋ƒ…์ƒท ๊ด€์ ์—์„œ ์ƒ๊ฐํ•˜๋ฉด ๋ฌธ์ œ๋ฅผ ๋ฐ”๋กœ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋น ๋ฅธ ํ”ผ๋“œ๋ฐฑ๊ณผ ํ˜‘์—…์„ ์ œ๊ณตํ•ด ์ฃผ์‹  PrimeReact ์œ ์ง€๋ณด์ˆ˜ํŒ€๊ณผ ํ›Œ๋ฅญํ•œ ์žฌํ˜„ ์˜ˆ์‹œ๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ์‹  ์› ๋ณด๊ณ ์ž์—๊ฒŒ ํฐ ๊ฐ์‚ฌ๋ฅผ ์ „ํ•ฉ๋‹ˆ๋‹ค.

Back to Blog

๊ด€๋ จ ๊ธ€

๋” ๋ณด๊ธฐ ยป

๋Œ€๊ทœ๋ชจ React ํ”„๋กœ์ ํŠธ๋ฅผ ์„œ์„œํžˆ ํŒŒ๋ฉธ์‹œํ‚ค๋Š” ์•„ํ‚คํ…์ฒ˜ ์‹ค์ˆ˜

๋ฌธ์ œ์  - ํด๋ผ์ด์–ธํŠธ์— ๋ฐ์ดํ„ฐ๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์Œ - useMemo ๋‚จ์šฉ - React Query๊ฐ€ ์˜จ์ฒด์ธ ํŽ˜์นญ์— ๋„ˆ๋ฌด ๋ณต์žกํ•ด์ง - ์˜ˆ์ธกํ•  ์ˆ˜ ์—†๋Š” ๋ฆฌ๋ Œ๋”๋ง - ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ค์›€...

State๋ฅผ ์ด๋™ํ•˜์—ฌ ๋ฆฌ๋ Œ๋”๋ง ์ตœ์ ํ™”

์†Œ๊ฐœ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ค๊ณ  ๋ถˆํ•„์š”ํ•œ ์žฌโ€‘๋ Œ๋”๋ง์„ ์ค„์ด๋Š” ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ ์ƒํƒœ๋ฅผ ๋‚ฎ์ถ”๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํŠนํžˆ ๊ทธ ์ƒํƒœ๊ฐ€ ํŠน์ • ๋ถ€๋ถ„์—๋งŒ ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ๊ฒฝ์šฐ์— ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค.

Linear Algebra๋ฅผ ํ™œ์šฉํ•ด React ์ƒํƒœ๋ฅผ ๊ฐ์‚ฌํ•˜๊ณ (๊ทธ ๋„๊ตฌ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค)

๋ฌธ์ œ: ์ƒํƒœ ์—”ํŠธ๋กœํ”ผ ๋Œ€๊ทœ๋ชจ React ์•ฑ์—์„œ๋Š” ๊ด€๋ จ๋œ ์ƒํƒœ๋ฅผ ์ˆ˜๋™์œผ๋กœ ๋™๊ธฐํ™”ํ•˜๊ฒŒ ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ ๋ชจ๋‘๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ๋ณธ ์ ์ด ์žˆ๊ฑฐ๋‚˜ ์ž‘์„ฑํ•œ ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค: tsx const user,โ€ฆ