๋๋ฒ์งธ๋ก๋ ์ํ์ ๊ฐ๊ฒฉ์์ผ๋ก ์ ๋ ฌํ๋ ๋ฒํผ์ ๊ตฌํํ์ต๋๋ค. ์๋ณธ ์ฌ์ดํธ์๋ ์ธ๊ธฐ๋์, ๋์ ํ๋งค์ ๋ฑ ๋ค์ํ ์ํ ์ ๋ ฌ ๋ฒํผ์ด ์์ง๋ง ์ ํฌ 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 ํ๋ผ๋ ์กฐ์ธ์ ํด์ฃผ์ จ๋๋ฐ .. ๊น๋จน๊ณ ์๋ค๊ฐ ์ด๋ฌํ ๋ฌธ์ ์ ์ด ๋ฐ์ใ ํ๋ค์ .. ๊ทธ๋๋ ์ด๋ฒ์ ์ด๋ ๊ฒ ๊ณ ์ํ์ผ๋ ๋ค์์ ์ ๋ ์ ๊น๋จน์ง ์์๊น์ ? ใ ใ
์ง์๋ ํฌ์คํธ๋ ํญ์ ์ฌ๋ฐ์ด์ ์์ฃผ ์ฑ๊ฒจ ๋ณด๊ณ ์์ต๋๋น ใ ใ ใ