๐Ÿ›’ ์‡ผํ•‘๋ชฐ ํด๋ก ์ฝ”๋”ฉ์„ ํ•˜๋ฉฐ ๋ฐฐ์šด ๊ฒƒ๋“ค #2

์›์ง€ยท2022๋…„ 12์›” 16์ผ
0

์Šคํ„ฐ๋”” ํšŒ๊ณ 

๋ชฉ๋ก ๋ณด๊ธฐ
3/5

๋‘๋ฒˆ์งธ๋กœ๋Š” ์ƒํ’ˆ์„ ๊ฐ€๊ฒฉ์ˆœ์œผ๋กœ ์ •๋ ฌํ•˜๋Š” ๋ฒ„ํŠผ์„ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค. ์›๋ณธ ์‚ฌ์ดํŠธ์—๋Š” ์ธ๊ธฐ๋„์ˆœ, ๋ˆ„์ ํŒ๋งค์ˆœ ๋“ฑ ๋‹ค์–‘ํ•œ ์ƒํ’ˆ ์ •๋ ฌ ๋ฒ„ํŠผ์ด ์žˆ์ง€๋งŒ ์ €ํฌ api์—๋Š” ํ•ด๋‹น ์ •๋ณด๋“ค์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋‚ฎ์€ ๊ฐ€๊ฒฉ์ˆœ, ๋†’์€ ๊ฐ€๊ฒฉ์ˆœ ๊ทธ๋ฆฌ๊ณ  ์ •ํ™•๋„์ˆœ์œผ๋กœ ์ƒํ’ˆ์„ ์ •๋ ฌํ•˜๋Š” ๋ฒ„ํŠผ์„ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ”€ ์ •๋ ฌ ๋ฒ„ํŠผ ๊ตฌํ˜„

const [product, setProduct] = useState();

const handleLowPrice = () => {
    let copyLow = [...products]
    copyLow.sort(function(a,b){
        return a.price - b.price;
      })
    setProduct(copyLow)
  }

  const handleHighPrice = () => {
    let copyHigh = [...products]
    copyHigh.sort(function(a,b){
        return b.price - a.price;
      })
    setProduct(copyHigh)
  }

  const handleAllProduct = () => {
    setProduct(products)
  }

...

{products.map((product) => (
          <Product/>
        ))}

๋จผ์ € ๋‚ฎ์€ ๊ฐ€๊ฒฉ์ˆœ, ๋†’์€ ๊ฐ€๊ฒฉ์ˆœ์œผ๋กœ ์ƒํ’ˆ์„ ์ •๋ ฌํ•˜๊ธฐ ์œ„ํ•ด ๊ธฐ์กด ์ƒํ’ˆ ๋ฐฐ์—ด์˜ ๋ณต์‚ฌ๋ณธ์„ ๋งŒ๋“ค์–ด sort ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‚ฎ์€ ๊ฐ€๊ฒฉ์ˆœ์œผ๋กœ ์ •๋ ฌ๋œ ๋ฐฐ์—ด copyLow, ๋†’์€ ๊ฐ€๊ฒฉ์ˆœ์œผ๋กœ ์ •๋ ฌ๋œ ๋ฐฐ์—ด copyHigh๋ฅผ ๋งŒ๋“  ๋’ค, ์ด ๊ฐ’๋“ค์„ setProduct ํ•จ์ˆ˜์— ๋„ฃ์–ด product๊ฐ’์„ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค. (์‚ฌ์‹ค ๋ฐฐ์—ด์„ ๋ณต์‚ฌํ•ด ์ •๋ ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์ด ์•„๋‹ ๊ฒƒ ๊ฐ™์€๋ฐ .. ์ œ๊ฐ€ ์•Œ๊ณ  ์žˆ๋Š” ๋ฐฉ๋ฒ• ์ค‘ ๊ฐ€์žฅ ์‰ฝ๊ณ  ๋น ๋ฅด๊ณ  .. ์ œํ’ˆ ๊ฐœ์ˆ˜๊ฐ€ ๋งŽ์ง€ ์•Š์•„ ์ด ๋ฐฉ๋ฒ•์„ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค ..)

Too many re-renders. React limits the number of renders to prevent an infinite loop.

๊ทธ๋Ÿฐ๋ฐ ์ด๋ ‡๊ฒŒ product๊ฐ’์„ ๋ฐ”๊พธ์ž ์œ„์™€ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ฆฌ์•กํŠธ๋Š” state์— ๋ณ€๊ฒฝ์ด ์žˆ์„ ๋•Œ, ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง ๋  ๋•Œ, ์ƒˆ๋กœ์šด props๊ฐ€ ๋“ค์–ด์˜ฌ ๋•Œ ๋ Œ๋”๋ง์ด ๋˜๋Š”๋ฐ ์ €์˜ ๊ฒฝ์šฐ setProduct๋กœ product์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ ค๊ณ  ํ•˜๋‹ค๋ณด๋‹ˆ ๊ณ„์†ํ•ด์„œ ๋ฆฌ๋žœ๋”๋ง์ด ์ผ์–ด๋‚˜ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

const filters = ['์ •ํ™•๋„์ˆœ', '๋‚ฎ์€ ๊ฐ€๊ฒฉ์ˆœ', '๋†’์€ ๊ฐ€๊ฒฉ์ˆœ'];
const [filter, setFilter] = useState(filters[0]);
onFilterChange={(filter) => setFilter(filter)}

<ul className={style.btns}>
      {filters.map((filter, index) => (
      <li className={style.btn_wrap} key={index}>
        <button className={style.btn} onClick={()=>onFilterChange(filter)}>{filter}</button>
      </li>))}
    </ul>

๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ๊ธฐ์กด์˜ ๋ฒ„ํŠผ๋“ค์„ ์ปดํฌ๋„ŒํŠธํ™”ํ•˜๋ฉฐ ์ˆ˜์ •ํ•œ ์ตœ์ข… ์ •๋ ฌ ๋ฒ„ํŠผ์€ ์œ„์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋จผ์ € ๋ฒ„ํŠผ์— ํด๋ฆญ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ํ•ด๋‹น ๋ฒ„ํŠผ ์ƒํƒœ๋ฅผ setFilter ํ•จ์ˆ˜๋กœ ๋ณ€๊ฒฝ์‹œํ‚ค๊ณ , ์ด๋ ‡๊ฒŒ ๋ณ€๊ฒฝ๋œ ์ƒํƒœ๋ฅผ ์ƒํ’ˆ ๋ชฉ๋ก ํŽ˜์ด์ง€์—์„œ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.

const filtered = getFilteredProducts(filter, products)

function getFilteredProducts(filter, products) {
  if(filter === '์ •ํ™•๋„์ˆœ') {
    return products;
  } else if(filter === '๋‚ฎ์€ ๊ฐ€๊ฒฉ์ˆœ') {
    let copyLow = [...products]
    copyLow.sort(function(a,b){
        return a.price - b.price;
      })
    return copyLow;
  } else if(filter === '๋†’์€ ๊ฐ€๊ฒฉ์ˆœ') {
    let copyHigh = [...products]
    copyHigh.sort(function(a,b){
      return b.price - a.price;
    })
    return copyHigh;
  }
}

{filtered.map((product) => (
          <Product/>
        ))}

๋ณ€๊ฒฝ๋œ filter์˜ ์ƒํƒœ์— ๋”ฐ๋ผ getFilteredProducts๋กœ ํ•ด๋‹น๋˜๋Š” ์ƒํ’ˆ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด, filtered์— ๋Œ€ํ•ด map์„ ๋Œ๋ฉฐ ์ œํ’ˆ์ด ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.

์งœ์ž” ! ๋ฐ”๋กœ ์ด๋ ‡๊ฒŒ์š”

๐Ÿ“‚ ํ›…์„ ์ด์šฉํ•œ ๋กœ์ง ๋ถ„๋ฆฌ

์ •๋ ฌ ๋ฒ„ํŠผ์€ ์ „์ฒด ์ƒํ’ˆ ํŽ˜์ด์ง€, ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ํŽ˜์ด์ง€, ๊ฒ€์ƒ‰๊ฒฐ๊ณผ ํŽ˜์ด์ง€ ์ด 3๊ณณ์—์„œ ์‚ฌ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ค‘๋ณต๋˜๋Š” ๋ฒ„ํŠผ ์š”์†Œ๋Š” sortButton ์ปดํฌ๋„ŒํŠธ, ๋ฐ˜๋ณต๋˜๋Š” ๋กœ์ง์€ useFilter ํ›…์„ ๋งŒ๋“ค์–ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

export default function useFilter (products) { 
  const filters = ['์ •ํ™•๋„์ˆœ', '๋‚ฎ์€ ๊ฐ€๊ฒฉ์ˆœ', '๋†’์€ ๊ฐ€๊ฒฉ์ˆœ'];
  const [filter, setFilter] = useState(filters[0]);
  const filtered = getFilteredProducts(filter, products);

  return [filters, filter, setFilter, filtered];
}

ํ›…์€ ์œ„์™€ ๊ฐ™์ด ์ •๋ ฌ ๋ฒ„ํŠผ์˜ ์ƒํƒœ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” state, ์ œํ’ˆ์„ ๊ฐ€๊ฒฉ์ˆœ์œผ๋กœ ์ •๋ ฌํ•˜๋Š” ํ•จ์ˆ˜ ๋“ฑ์„ ํฌํ•จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ „์ฒด ์ƒํ’ˆ ํŽ˜์ด์ง€, ์นดํ…Œ๊ณ ๋ฆฌ ํŽ˜์ด์ง€์—์„œ๋Š” ๋ฌธ์ œ ์—†์ด ์ž‘๋™ํ•˜๋˜ ๋ฒ„ํŠผ์ด ์„œ์น˜ํŽ˜์ด์ง€์—์„œ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ฝ˜์†”์— ๊ฐ’์„ ์ฐ์–ด๋ณด๋ฉฐ ๋ฌธ์ œ์ ์„ ํ™•์ธํ•ด๋ณด๋‹ˆ

๊ฒ€์ƒ‰๊ฒฐ๊ณผ ๊ฐ’์ด products๋กœ ๋“ค์–ด์˜ค๊ธฐ ์ „์— useFilter ํ›…์ด ์‹คํ–‰๋˜์–ด undefined๋ฅผ map์œผ๋กœ ๋Œ๋ฆฌ๋ ค ํ•˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

export default function useFilter (products) { 
  const filters = ['์ •ํ™•๋„์ˆœ', '๋‚ฎ์€ ๊ฐ€๊ฒฉ์ˆœ', '๋†’์€ ๊ฐ€๊ฒฉ์ˆœ'];
  const [filter, setFilter] = useState(filters[0]);
  if(!products) return
  const filtered = getFilteredProducts(filter, products);

  return [filters, filter, setFilter, filtered];
}

์˜ค๋ฅ˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์ƒํ’ˆ์ด ์—†๋Š” ๊ฒฝ์šฐ, ํ›…์„ ์ข…๋ฃŒ ์‹œ์ผœ ์ƒํ’ˆ์„ ์žฌ์ •๋ ฌํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š๋„๋ก ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

undefined is not iterable
--.map is not a function

๊ทธ๋Ÿฌ๋‚˜ .. ์œ„์™€ ๊ฐ™์€ ๋˜ ๋‹ค๋ฅธ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค ..

์ฒ˜์Œ์—๋Š” ์œ„์—์„œ ์ž‘์„ฑํ•œ ์ƒํ’ˆ์ด ์—†๋Š” ๊ฒฝ์šฐ์— ๋Œ€ํ•œ ์˜ˆ์™ธ์ฒ˜๋ฆฌ๊ฐ€ ์ž˜๋ชป๋œ ๊ฒƒ์ธ ์ค„ ์•Œ๊ณ  .. ์กฐ๊ฑด๋ฌธ์„ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ์ž‘์„ฑํ–ˆ๋Š”๋ฐ์š” .. ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค ๐Ÿ’ข

๊ฒฐ๊ตญ useFilter ํ›… ์ž์ฒด๋ฅผ ํ˜ธ์ถœํ•ด ์ƒํ’ˆ ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” 'filtered' ๋ฐฐ์—ด์—” ์ œ๋Œ€๋กœ ๊ฐ’์ด ์ฐํžˆ๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ๊ณ  .. ๋ฌธ์ œ๋Š” ๋‹ค๋ฅธ ๊ณณ์— ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค.

const [filters, setFilter, filtered] = useFilter(search)

์•ฝ 2์‹œ๊ฐ„์„ ํ—ค๋งจ ๋์— ์ฐพ์€ ๋ฌธ์ œ์ ์„ ๋ฐ”๋กœ ์ด ๋ถ€๋ถ„์ด์—ˆ์Šต๋‹ˆ๋‹ค.

export default function useFilter (products) {
...
  return [filters, filter, setFilter, filtered];
}

useFilter๋Š” filters, filter, setFilter, filtered๋ฅผ ๋ฐฐ์—ด์— ๋‹ด์•„ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ €๋Š” ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ํŽ˜์ด์ง€์—์„œ๋Š” filter๊ฐ€ ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ‹๋Œ€๋กœ ๋‚˜๋จธ์ง€ ๋ณ€์ˆ˜๋งŒ ๋ฐ›์•„์˜ค๋Š” ์•…ํ–‰์„ ์ €์งˆ๋ €์Šต๋‹ˆ๋‹ค .. ๊ทธ๋Ÿฌ๋‚˜ ๋ฐฐ์—ด์€ ์ˆœ๋ฒˆ์ด ์žˆ๋Š” ๋ฐ์ดํ„ฐ์ง€์š” ..? ๊ฒฐ๊ตญ ๋ฐฐ์—ด์˜ ์ˆœ์„œ๋ฅผ ๋ฌด์‹œํ•œ ์ฑ„ ๊ฐ’์„ ๋ถˆ๋Ÿฌ์˜จ ๊ฒƒ์ด ๋ฌธ์ œ์˜€์Šต๋‹ˆ๋‹ค ..

export default function useFilter (products) { 
  const filters = ['์ •ํ™•๋„์ˆœ', '๋‚ฎ์€ ๊ฐ€๊ฒฉ์ˆœ', '๋†’์€ ๊ฐ€๊ฒฉ์ˆœ'];
  const [filter, setFilter] = useState(filters[0]);
  if(!products) return undefined;
  const filtered = getFilteredProducts(filter, products);

  return {filters, filter, setFilter, filtered};
}

์ตœ์ข…์ ์œผ๋กœ๋Š” ๊ฐ์ฒด๋กœ ๊ฐ’์„ ๋ฆฌํ„ดํ•ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์ˆ˜์ •ํ•˜๋ฉด ์ˆœ์„œ์™€ ๋ฌด๊ด€ํ•˜๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ์“ธ ์ˆ˜ ์žˆ์–ด ์ง€๊ธˆ๊ณผ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ• ๋ฆฌ ์—†๊ฒ ์ฃ  ..

๋ถ„๋ช… ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋•Œ ์ด์‚ญ๋‹˜๊ป˜์„œ ๋ฐฐ์—ด์ด ์•„๋‹Œ ๊ฐ์ฒด๋กœ ๊ฐ’์„ return ํ•˜๋ผ๋Š” ์กฐ์–ธ์„ ํ•ด์ฃผ์…จ๋Š”๋ฐ .. ๊นŒ๋จน๊ณ  ์žˆ๋‹ค๊ฐ€ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ์ ์ด ๋ฐœ์ƒใ…‡ํ–ˆ๋„ค์š” .. ๊ทธ๋ž˜๋„ ์ด๋ฒˆ์— ์ด๋ ‡๊ฒŒ ๊ณ ์ƒํ–ˆ์œผ๋‹ˆ ๋‹ค์Œ์—” ์ ˆ๋Œ€ ์•ˆ ๊นŒ๋จน์ง€ ์•Š์„๊นŒ์š” ? ใ…Žใ…Ž

1๊ฐœ์˜ ๋Œ“๊ธ€

comment-user-thumbnail
2022๋…„ 12์›” 16์ผ

์ง€์›๋‹˜ ํฌ์ŠคํŠธ๋Š” ํ•ญ์ƒ ์žฌ๋ฐŒ์–ด์„œ ์ž์ฃผ ์ฑ™๊ฒจ ๋ณด๊ณ  ์žˆ์Šต๋‹ˆ๋‹น ใ…Žใ…Žใ…Ž

๋‹ต๊ธ€ ๋‹ฌ๊ธฐ