ํ™ˆ [Error] Warning: Received true for a non-boolean attribute ์—๋Ÿฌ ํ•ด๊ฒฐ
ํฌ์ŠคํŠธ
์ทจ์†Œ

[Error] Warning: Received true for a non-boolean attribute ์—๋Ÿฌ ํ•ด๊ฒฐ

๐Ÿ”บ ์—๋Ÿฌ ๋ฐœ์ƒ ์›์ธ์€?

styled-components ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋˜ ์ค‘, ํผ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์„œ boolean ๊ฐ’์œผ๋กœ ๋„˜์–ด๊ฐ€ props๋กœ ์†์„ฑ์„ ์ „๋‹ฌํ•ด์ฃผ๋Š”๋ฐ, ์ด๋•Œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€๋‹ค.

react-dom.development.js:86 Warning: Received true for a non-boolean attribute active.
If you want to write it to the DOM, pass a string instead: active=โ€trueโ€ or active={value.toString()}.

์ด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ด์œ ๋Š” React๊ฐ€ active๋ผ๋Š” prop์„ DOM ์š”์†Œ์˜ ํ‘œ์ค€ ์†์„ฑ์œผ๋กœ ์ธ์‹ํ•˜์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ํ˜„์žฌ ์‹ค์ œ DOM ์ „๋‹ฌ์ด ๋˜๊ณ , ์—๋Ÿฌ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ด์˜€๋‹ค.


โŒ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ์ „ ์ฝ”๋“œ๋Š”?

๊ธฐ์กด์˜ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{contentTabs.map((tab, idx) => (
  <ContentTabItems key={idx} active={currentTabMode === idx} onClick={() => handlerTabClick(idx)}>
    {tab.title}
  </ContentTabItems>
))}

// =============== ์ฝ˜ํ…์ธ  Vlog or Blog ํƒญ ===============
const ContentTabItems = styled.li<{ active: boolean }>`
  ${({ theme }) => theme.common.flexCenterRow};
  cursor: pointer;
  font-weight: ${({ active }) => (active ? 600 : 500)};
  letter-spacing: 0.5px;
  font-size: 17px;
  height: 45px;
  color: ${({ active }) => (active ? 'var(--black-hunt)' : 'var(--gray-dark)')};
  position: relative;
`;

active ์†์„ฑ์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์ด๋‹ค.


โญ•๏ธ ๊ทธ๋Ÿผ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•ด์•ผํ• ๊นŒ?

๋‚ด๊ฐ€ ์—๋Ÿฌ๋ฅผ ํ•ด๊ฒฐํ•œ ๋ฐฉ๋ฒ•์€ transient props ($)์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด์˜€๋‹ค.

styled-components ๊ณต์‹์‚ฌ์ดํŠธ์— ์ž์„ธํ•˜๊ฒŒ ๋‚˜์™€์žˆ๋‹ค. ๋‚˜๋Š” ํ•œ์ฐธ ์‚ฝ์งˆํ•˜๋‹ค๊ฐ€ ๊ณต์‹๋ฌธ์„œ์—์„œ ์ฐพ์€๊ฑฐ์ง€๋งŒโ€ฆ ๊ณต์‹๋ฌธ์„œ๋ฅผ ์ž˜ ๋ณด์ž..!!!

transient props ($)

  • $ ๋Š” styled-components์˜ v5.1.0๋ถ€ํ„ฐ ๋„์ž…๋œ transient props์˜ ์ผ๋ถ€๋‹ค.
  • styled-components์—์„œ ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌ๋œ ๋ชจ๋“  props๋Š” DOM ์š”์†Œ์—๋„ ์ „๋‹ฌ๋˜๋Š”๋ฐ, DOM์—์„œ ์ง€์›ํ•˜์ง€ ์•Š๋Š” prop๋ฅผ ๋ฐ›๋Š” ๊ฒฝ์šฐ React๋Š” ๋‚ด๊ฐ€ ์œ„์—์„œ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ์ฒ˜๋Ÿผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.
  • ์ด๋•Œ, styled-components๋Š” transient props๋ผ๋Š” ๊ฐœ๋…์„ ๋„์ž…ํ•œ ๊ฒƒ์ด๋‹ค.
  • transient props๋Š” styled-components๋กœ ์ „๋‹ฌ๋˜์ง€๋งŒ ์‹ค์ œ DOM ์š”์†Œ์—๋Š” ์ „๋‹ฌ๋˜์ง€ ์•Š๋Š” props๋‹ค.
  • transient props๋Š” $ ์ ‘๋‘์‚ฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ •์˜ํ•œ๋‹ค.

๋‚ด๊ฐ€ ์ˆ˜์ •ํ•œ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. ์ˆ˜์ • ์ „ ์ฝ”๋“œ๋ฅผ ๋น„๊ตํ•˜๋ฉด $๋ฅผ ์‚ฌ์šฉ์œ ๋ฌด๋งŒ ๋‹ค๋ฅด์ง€ ์ฝ”๋“œ๋Š” ๋™์ผํ•˜๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{contentTabs.map((tab, idx) => (
  <ContentTabItems key={idx} $active={currentTabMode === idx} onClick={() => handlerTabClick(idx)}>
    {tab.title}
  </ContentTabItems>
))}

// =============== ์ฝ˜ํ…์ธ  Vlog or Blog ํƒญ ===============
const ContentTabItems = styled.li<{ $active: boolean }>`
  ${({ theme }) => theme.common.flexCenterRow};
  cursor: pointer;
  letter-spacing: 0.5px;
  font-size: 17px;
  height: 45px;
  font-weight: ${({ $active }) => ($active ? 600 : 500)};
  color: ${({ $active }) => ($active ? 'var(--black-hunt)' : 'var(--gray-dark)')};
  position: relative;
`;

์œ„์˜ ์ฝ”๋“œ์—์„œ, $active prop์€ ContentTabItems ์ปดํฌ๋„ŒํŠธ์—๋งŒ ์ „๋‹ฌ๋˜๊ณ  ์‹ค์ œ DOM ์š”์†Œ์—๋Š” ์ „๋‹ฌ๋˜์ง€ ์•Š๊ณ , ์ด๋ ‡๊ฒŒํ•˜๋ฉด React ๊ฒฝ๊ณ ๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด ๊ธฐ์‚ฌ๋Š” ์ €์ž‘๊ถŒ์ž์˜ CC BY 4.0 ๋ผ์ด์„ผ์Šค๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.

[LearningTS] Chapter09. ํƒ€์ž… ์ œํ•œ์ž

[LearningTS] Chapter10. ์ œ๋„ค๋ฆญ