JS/React

[React] #10 ๋ฆฌ์•กํŠธ : Key

emayom 2021. 9. 10. 12:25

๐Ÿ”ฅ Warning: Each child in a list should have a unique "key" prop. ๐Ÿ”ฅ

 

์ต์ˆ™ํ•œ ์›Œ๋‹์ด๋‹ค ,,,!

๋ฆฌ์•กํŠธ์—์„œ map์„ ์‚ฌ์šฉํ•ด์„œ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ํ•˜๋‚˜์”ฉ ๋งŒ๋“ค์–ด๋‚ผ ๋•Œ

ํ‚ค ๊ฐ’์„ ์ฃผ์ง€ ์•Š์œผ๋ฉด ํ•ญ์ƒ ๋ณด๊ฒŒ ๋˜๋Š” ๋ฌธ๊ตฌ์ด๋‹ค.

๋ฆฌ์•กํŠธ์—์„œ key๋Š” ๋„๋Œ€์ฒด ์™œ ์ค‘์š”ํ•œ ๊ฒƒ์ผ๊นŒ?

 


Key ( index โŒ )

 

๋ฆฌ์•กํŠธ์—์„œ key๋Š” ๊ฝค ์ค‘์š”ํ•œ ๋“ฏ ๋ณด์ธ๋‹ค.

๊ฒฝ์šฐ์— ๋”ฐ๋ผ ํ‚ค๋ฅผ ์คฌ์„ ๋•Œ์™€ ์•ˆ ์คฌ์„ ๋•Œ์˜ ๋ฆฌ๋ Œ๋”๋ง์—๋Š” ํฐ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค.

 

๋ฐฐ์—ด์ด๋‹ˆ๊นŒ key๋ฅผ ํŽธํ•˜๊ฒŒ index๋กœ ์ฃผ๋ฉด ์•ˆ ๋˜๋‚˜?

์–ด์ฐจํ”ผ ์ž๊ธฐ๋“ค๋ผ๋ฆฌ ๋‹ค๋ฅด๋ฉด ์œ ๋‹ˆํฌํ•œ ๊ฒƒ ์•„๋‹Œ๊ฐ€๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค ใ…Žใ…Žใ…Ž

๊ฒฐ๋ก ์€ ์•„๋‹ˆ๋‹ค! ๊ทธ๋ ‡๊ฒŒ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด ์•„๋ž˜์™€ ๊ฐ™์ด

์นด๋“œ๊ฐ€ ๋‹ค๋ฅธ ์ˆœ์„œ๋กœ ์„ž์ธ ๋ฐฐ์—ด์˜ ํŒจ๊ฐ€ ์žˆ๋‹ค๊ณ  ํ–ˆ์„ ๋•Œ,

์ด๊ฒƒ์„ 1์ดˆ๋งˆ๋‹ค ์นด๋“œ๋ฅผ ์„ž๋“ฏ์ด ํŒจ ๋ฐฐ์—ด์„ ๋ฐ”๊ฟ”์ค€๋‹ค๊ณ  ๊ฐ€์ •ํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด์ž.

(์ด๋•Œ ํ‚ค๋ฅผ ํ•œ ๋ฒˆ์€ id ๊ฐ’์œผ๋กœ, ๋‹ค๋ฅธ ํ•œ ๋ฒˆ์€ index ๊ฐ’์œผ๋กœ ์ค„ ์˜ˆ์ •์ด๋‹ค.)

 

const oneCard = [
  [
    { id: "1", value: "spaede" },
    { id: "2", value: "diamond" },
    { id: "3", value: "heart" },
    { id: "4", value: "clobs" }
  ],
  [
    { id: "4", value: "clobs" },
    { id: "1", value: "spaede" },
    { id: "2", value: "diamond" },
    { id: "3", value: "heart" }
  ],
  [
    { id: "3", value: "heart" },
    { id: "1", value: "spaede" },
    { id: "2", value: "diamond" },
    { id: "4", value: "clobs" }
  ],
  [
    { id: "2", value: "diamond" },
    { id: "1", value: "spaede" },
    { id: "3", value: "heart" },
    { id: "4", value: "clobs๏ธ" }
  ]
];

 

์ธ๋ฑ์Šค๋ฅผ ํ‚ค ๊ฐ’์œผ๋กœ?

์ธ๋ฑ์Šค๋ฅผ ํ‚ค ๊ฐ’์œผ๋กœ ์ฃผ๋ฉด ๋ Œ๋”๋ง์ด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•œ ๋’ค tab ํ‚ค๋กœ ํฌ์ปค์Šค๋ฅผ ์žก์•„๋ณด๋ฉด

 

const App = () => {
  //๊ฐ€์žฅ ์ฒซ๋ฒˆ์งธ ๋ฐฐ์—ด๋กœ setํ•œ ๋’ค
  const [cards, setCards] = React.useState(oneCard[0]);
  
  //1์ดˆ๋งˆ๋‹ค ์นด๋“œ๋ฅผ ์„ž๋Š”๋‹ค.
  React.useEffect(() => {
    const interval = setInterval(() => {
      const random = Math.floor(Math.random() * 3);
      setCards(oneCard[random]);
    }, 1000);
    
    return () => {
      clearInterval(interval);
    };
  }, []);
  
  return (
    <>
      {cards.map((card, index) => (
        <div key={index}>
          <button>
            {card.value}
          </button>
        </div>
      ))}
    </>
  );

 

 

ํฌ์ปค์Šค๋Š” ์ด๋™ํ•˜์ง€ ์•Š์ง€๋งŒ ๋ฒ„ํŠผ์— ์ ํžŒ ์นด๋“œ๋ช…๋งŒ ๋ณ€ํ•œ๋‹ค.

ํ‚ค๋ฅผ ์•ˆ ์ค€ ๊ฒƒ๊ณผ ๋‹ค๋ฅผ ๊ฒŒ ์—†๋‹ค. 

์™œ์ผ๊นŒ? ์ƒ๊ฐ ๋ณด๋ฉด ์ธ๋ฑ์Šค์˜ ์ƒํƒœ๋Š” ๋ณ€ํ•˜์ง€ ์•Š๋Š”๋‹ค.

 

+)

๋ฆฌ์•กํŠธ์—์„œ๋Š” ๋ฆฌ์ŠคํŠธ ํ•ญ๋ชฉ์— ๋ช…์‹œ์ ์œผ๋กœ key๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ index๋ฅผ key๋กœ ์‚ฌ์šฉ

 

 

 

ํ•˜์ง€๋งŒ ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ๊ฑด ์„ž์ธ ํŒจ๋ฅผ ๋”ฐ๋ผ๊ฐ€๋Š” ๊ฒƒ..!

 

๋ฆฌ์•กํŠธ๋Š” ๋ฆฌ๋žœ๋”๋ง ๊ณผ์ •์—์„œ ๋ณ€ํ•˜์ง€ ์•Š์€ ํ‚ค == ์ธ๋ฑ์Šค๋ฅผ ๋ณด๊ณ 

๋™์ผํ•œ ์ƒํƒœ๋ผ๊ณ  ํŒ๋‹จํ•˜๊ณ  ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์€ ์ฑ„ ๋ฒ„ํŠผ์˜ ์ด๋ฆ„๋งŒ ์—…๋ฐ์ดํŠธํ•˜๊ฒŒ ๋œ๋‹ค.

 

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ „์ฒด๋ฅผ ์˜ฎ๊ธฐ๋“ฏ์ด!
์ปดํฌ๋„ŒํŠธ ์ž์ฒด์˜ ์œ„์น˜๋ฅผ ๋ฐ”๊พธ๋ฉฐ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” unique key๋ฅผ ์ค˜์•ผ ํ•œ๋‹ค.

key์— id ๊ฐ’์„ ๋„ฃ์–ด์ฃผ๋ฉด ํ•ด๋‹น ์นด๋“œ๋ฅผ ๋”ฐ๋ผ๊ฐ€๋ฉฐ ํฌ์ปค์Šค๊ฐ€ ์ž˜ ์œ ์ง€๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค!

 

const App = () => {
  //๊ฐ€์žฅ ์ฒซ๋ฒˆ์งธ ๋ฐฐ์—ด๋กœ setํ•œ ๋’ค
  const [cards, setCards] = React.useState(oneCard[0]);
  
  //1์ดˆ๋งˆ๋‹ค ์นด๋“œ๋ฅผ ์„ž๋Š”๋‹ค.
  React.useEffect(() => {
    const interval = setInterval(() => {
      const random = Math.floor(Math.random() * 3);
      setCards(oneCard[random]);
    }, 1000);
    
    return () => {
      clearInterval(interval);
    };
  }, []);
  
  return (
    <>
      {cards.map((card) => (
        <div key={card.id}>
          <button>
            {card.value}
          </button>
        </div>
      ))}
    </>
  );

 

 

๋ฆฌ์•กํŠธ์—์„œ key๋Š”

๋ฆฌ์•กํŠธ๊ฐ€ ์–ด๋–ค ํ•ญ๋ชฉ์„ ๋ณ€๊ฒฝ, ์ถ”๊ฐ€ ๋˜๋Š” ์‚ญ์ œํ•  ๊ฒฝ์šฐ ์‹๋ณ„ํ•˜๋Š” ๊ฒƒ์„ ๋„์™€์ค€๋‹ค!

key๋Š” ์—˜๋ฆฌ๋จผํŠธ์— ์•ˆ์ •์ ์ธ ๊ณ ์œ ์„ฑ์„ ๋ถ€์—ฌํ•˜๊ธฐ ์œ„ํ•ด ๋ฐฐ์—ด ๋‚ด๋ถ€์˜ ์—˜๋ฆฌ๋จผํŠธ์— ์ง€์ •ํ•ด์•ผ ํ•œ๋‹ค.

๊ณต์‹ ๋ฌธ์„œ์—์„œ๋„ ์ธ๋ฑ์Šค๋Š” ์ตœ์ตœ์ตœ์ตœํ›„์˜ ์ˆ˜๋‹จ์œผ๋กœ ์‚ฌ์šฉํ•˜๋ผ๊ณ  ๋ช…์‹œํ•ด๋‘์—ˆ๋‹ค.

 

ํŠนํžˆ๋‚˜ !!!!

ํ•ญ๋ชฉ์˜ ์ˆœ์„œ๊ฐ€ ๋ฐ”๋€” ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์—๋Š” key์— ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•˜์ง€ ์•Š์œผ๋ฉฐ,

์„ฑ๋Šฅ ์ €ํ•˜๋‚˜ ์ปดํฌ๋„ŒํŠธ์˜ state์™€ ๊ด€๋ จ๋œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค!!

 

 


 

 

๋ฆฌ์ŠคํŠธ์™€ Key – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

Index as a key is an anti-pattern

So many times I have seen developers use the index of an item as its key when they render a list.

robinpokorny.medium.com

 

โš ๏ธ ์•„๋ž˜ ๋‚ด์šฉ์€ ๋ชจ๋‘ ๊ฐœ์ธ์ ์ธ ์ฐธ๊ณ  / ๊ธฐ๋ก์„ ์œ„ํ•œ ์šฉ๋„์ž…๋‹ˆ๋‹ค. ์ฐธ๊ณ ํ•ด์ฃผ์‹œ๊ณ  ํŽธ์•ˆํ•˜๊ฒŒ ๋ด์ฃผ์„ธ์š” :)  โš ๏ธ
***    ํ˜น์‹œ๋ผ๋„ ์ž˜๋ชป๋œ ์ •๋ณด๊ฐ€ ์žˆ๋‹ค๋ฉด  ์–ธ์ œ๋“ ์ง€ ์•Œ๋ ค์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค  !    ***