
리액트로 만들고 싶었지만 머릿속 백지장 이슈로 자바스크립트로 먼저 제작하였다
function App() {
const fruitArr = [
{fruit: "딸기", producer: "국내산", season: "봄", calorie: 27},
{fruit: "체리", producer: "수입산", season: "봄", calorie: 60},
{fruit: "키위", producer: "수입산", season: "봄", calorie: 55},
{fruit: "파인애플", producer: "수입산", season: "봄", calorie: 55},
{fruit: "오렌지", producer: "국내산", season: "봄",
.
.
.
]
let clickedArr = [];
const checkHandler = (target) => {
const checkbox = document.getElementsByName(target.name);
// 체크 다중선택 방지
for (let i = 0; i < checkbox.length; i++) {
if (checkbox[i] !== target) {
checkbox[i].checked = false;
}
}
// 체크 변경
const index = clickedArr.findIndex(item => item.name === target.name);
if (index > -1) {
clickedArr[index].value = target.value;
} else {
clickedArr.push({name: target.name, value: target.value});
}
// 체크 해제
if (target.checked) {
if (target.name === "calorie") {
calorieFilter(target);
}
} else {
if (index > -1) {
clickedArr.splice(index, 1);
}
}
// Q. 칼로리 부분을 함수로 정의하지 않고, 바로 필터값을 줄 수 있지 않을까?
function calorieFilter() {
let clickedCalorie;
if (target.value === "0") {
clickedCalorie = fruitArr.filter((fruit) => fruit.calorie < 40);
} else if (target.value === "40") {
clickedCalorie = fruitArr.filter((fruit) => fruit.calorie >= 40 && fruit.calorie < 60);
} else if (target.value === "60") {
clickedCalorie = fruitArr.filter((fruit) => fruit.calorie >= 60);
}
clickedArr = clickedArr.filter((item) => item.name !== "calorie");
clickedArr.push({name: "calorie", value: target.value, fruits: clickedCalorie});
}
console.log(clickedArr);
}
// 결과 보여주기
const resultFruit = () => {
let filteredFruits = [...fruitArr];
// Q. 굳이 if문으로 안해도 되지 않을까?
clickedArr.forEach((condition) => {
if (condition.name === "producer") {
filteredFruits = filteredFruits.filter(
(fruit) => fruit.producer === condition.value
);
} else if (condition.name === "season") {
filteredFruits = filteredFruits.filter((fruit) =>
fruit.season.includes(condition.value)
);
} else if (condition.name === "calorie") {
// calorie 조건 필터링
filteredFruits = filteredFruits.filter((fruit) =>
condition.fruits.some(
(calorieFruit) => calorieFruit.fruit === fruit.fruit
)
);
}
});
const resultDiv = document.getElementById("result");
if (filteredFruits.length === 0) {
resultDiv.innerHTML = `<p>다시 선택해주세요</p>`;
} else {
resultDiv.innerHTML = filteredFruits
.map((fruit) => `<p>${fruit.fruit}</p>`)
.join(""); //쉼표 제거
}
}
return (
<div className="App">
<div className="wrap">
<h6>1.국내산인가요, 수입산인가요?</h6>
<label><input type="checkbox" name="producer" value="domestic" onChange={(e) => checkHandler(e.target)}/>국내산</label>
<label><input type="checkbox" name="producer" value="imported" onChange={(e) => checkHandler(e.target)}/>수입산</label>
</div>
<div className="wrap">
<h6>2. 계절은 언제인가요?</h6>
<label><input type="checkbox" name="season" value="srping"
onChange={(e) => checkHandler(e.target)}/>봄</label>
<label><input type="checkbox" name="season" value="summer"
onChange={(e) => checkHandler(e.target)}/>여름</label>
<label><input type="checkbox" name="season" value="autumn"
onChange={(e) => checkHandler(e.target)}/>가을</label>
<label><input type="checkbox" name="season" value="winter"
onChange={(e) => checkHandler(e.target)}/>겨울</label>
</div>
<div className="wrap">
<h6>3. 칼로리는 얼마인가요?</h6>
<label><input type="checkbox" name="calorie" value="0" onChange={(e) => checkHandler(e.target)}/>40
미만</label>
<label><input type="checkbox" name="calorie" value="40" onChange={(e) => checkHandler(e.target)}/>40
이상~60 미만</label>
<label><input type="checkbox" name="calorie" value="60" onChange={(e) => checkHandler(e.target)}/>60 이상</label>
</div>
<button onClick={resultFruit}>
나에게 맞는 과일 보여주기
</button>
<div id="result"></div>
</div>
);
}
export default App;
function calorieFilter() {
let clickedCalorie;
if (target.value === "0") {
clickedCalorie = fruitArr.filter((fruit) => fruit.calorie < 40);
} else if (target.value === "40") {
clickedCalorie = fruitArr.filter((fruit) => fruit.calorie >= 40 && fruit.calorie < 60);
} else if (target.value === "60") {
clickedCalorie = fruitArr.filter((fruit) => fruit.calorie >= 60);
}
clickedArr = clickedArr.filter((item) => item.name !== "calorie");
clickedArr.push({name: "calorie", value: target.value, fruits:clickedCalorie});
}
if (target.name === "calorie") {
let clickedCalorie;
if (target.value === "0") {
clickedCalorie = fruitArr.filter((fruit) => fruit.calorie < 40);
} else if (target.value === "40") {
clickedCalorie = fruitArr.filter((fruit) => fruit.calorie >= 40 && fruit.calorie < 60);
} else if (target.value === "60") {
clickedCalorie = fruitArr.filter((fruit) => fruit.calorie >= 60);
}
clickedArr = clickedArr.filter((item) => item.name !== "calorie");
clickedArr.push({name: "calorie", value: target.value, fruits:clickedCalorie});
}
=> 함수로 정의하지 않고, target.name === "calorie" 일 때만 실행 가능한 구문으로 변경하였다.
clickedArr.forEach((condition) => {
if (condition.name === "producer") {
filteredFruits = filteredFruits.filter((fruit) => fruit.producer === condition.value;
} else if (condition.name === "season") {
filteredFruits = filteredFruits.filter((fruit) => fruit.season.includes(condition.value));
} else if (condition.name === "calorie") {
filteredFruits = filteredFruits.filter((fruit) => condition.fruits.some((calorieFruit) => calorieFruit.fruit === fruit.fruit));
}
});
const filterFunctions = {
producer: (fruits, condition) =>
fruits.filter((fruit) => fruit.producer === condition.value),
season: (fruits, condition) =>
fruits.filter((fruit) => fruit.season.includes(condition.value)),
calorie: (fruits, condition) =>
fruits.filter((fruit) => condition.fruits.some((calorieFruit) => calorieFruit.fruit === fruit.fruit)
),
};
clickedArr.forEach((condition) => {
const filterFunction = filterFunctions[condition.name];
if (filterFunction) {
filteredFruits = filterFunction(filteredFruits, condition);
}
});
=> producer, season, calorie를 기준으로 데이터를 필터링하는 함수를 만들고, 체크된 답지 리스트인 clickedArr를 해당 필터 함수로 필터링한다.