카드를 이름과 마나 코스트 순으로 정렬을 바꿀 수 있게 하고 모든 직업군에서 적용되는 중립 카드를 안 볼 수 있게 기능을 추가해보려고 합니다.
정렬
// 현재 정렬 상태 (1,2,3,4)
const [filterOrder, setFilterOrder] = useState(1);
// 중립 카드 온오프
const [onNeutral, setOnNeutral] = useState(true);
// 직업 선택 시 카드 리스트 저장
const [currentCard, setCurrentCard] = useState(props.currentHeroCard);
// 이름 순 카드 오름차순 정렬
const nameAscendSort = () => {
setFilterOrder(1);
const sortedArray = currentCard;
sortedArray.sort((a, b) => a.name.localeCompare(b.name));
setCurrentCard(sortedArray);
setOnNeutral(true);
};
// 이름 순 카드 내림차순 정렬
const nameDescendSort = () => {
setFilterOrder(2);
const sortedArray = props.currentHeroCard;
sortedArray.sort((a, b) => b.name.localeCompare(a.name));
setCurrentCard(sortedArray);
setOnNeutral(true);
};
// 마나 코스트 순 카드 오름차순 정렬
const manaCostAscendSort = () => {
setFilterOrder(3);
const sortedArray = props.currentHeroCard;
sortedArray.sort((a, b) => a.manaCost - b.manaCost);
setCurrentCard(sortedArray);
setOnNeutral(true);
};
// 마나 코스트 순 카드 내림차순 정렬
const manaCostDescendSort = () => {
setFilterOrder(4);
const sortedArray = props.currentHeroCard;
sortedArray.sort((a, b) => b.manaCost - a.manaCost);
setCurrentCard(sortedArray);
setOnNeutral(true);
};
마나 코스트는 모든 카드에 들어 있으며 숫자 타입입니다.
단순히 객체 안의 manaCost 요소를 비교해 오름차순과 내림차순으로 정렬할 수 있습니다.
그리고 sort 메서드는 원본을 바꾸는 메서드이기 때문에 복제본을 만들고 정렬한 다음 변수에 넣어줘야 원본이 바뀌지 않습니다.
이름을 정렬하는 데서 문제가 하나 생겼는데 타입스크립트에서 이름을 가지고 sort에 비교 함수로 수를 비교하듯이 적었더니 문자열은 연산할 수 없다는 에러가 떴습니다.
그래서 다음과 같이 localeCompare 메서드를 사용해 해결할 수 있었습니다.
현재 정렬 상태는 기본적으로 이름 오름차순으로 정렬된 데이터가 오기에 이 상태를 1로 부여하고 이름 내림차순, 마나 코스트 오름차순, 마나 코스트 내림차순을 순서대로 2, 3, 4에 연결했습니다.
return (
<div>
<div className="flex mx-48 text-gray-200 text-3xl">
<button
className="m-4 p-2 pt-1 rounded-xl"
onClick={nameAscendSort}
style={{ border: filterOrder === 1 ? "1px solid white" : "" }}
>
이름▲
</button>
<button
className="m-4 p-2 pt-1 rounded-xl"
onClick={nameDescendSort}
style={{
border: filterOrder === 2 ? "1px solid white" : "",
}}
>
이름▼
</button>
<button
className="m-4 p-2 pt-1 rounded-xl"
onClick={manaCostAscendSort}
style={{
border: filterOrder === 3 ? "1px solid white" : "",
}}
>
비용▲
</button>
<button
className="m-4 p-2 pt-1 rounded-xl"
onClick={manaCostDescendSort}
style={{
border: filterOrder === 4 ? "1px solid white" : "",
}}
>
비용▼
</button>
</div>
</div>
)
위와 같이 관리되는 변수를 통해 현재 정렬 상태가 어떤 것인지 볼 수 있습니다.
중립 온오프
모든 직업에서 중립카드는 공통으로 포함되기에 현재 직업 카드만 볼 수 있게 하였습니다.
const neutralFilter = () => {
if (onNeutral) {
setCurrentCard(currentCard.filter((el) => el.classId !== 12));
} else {
setCurrentCard(props.currentHeroCard);
}
setOnNeutral(!onNeutral);
};
다음과 같이 하나의 함수로 버튼에 적용해 온오프 형식으로 구현했습니다.
<button
className="m-4 p-2 pt-1 rounded-xl"
onClick={neutralFilter}
style={{ color: onNeutral ? "blue" : "red" }}
>
{onNeutral ? `중립 O` : `중립 X`}
</button>
또, 위의 필터링과 동시 적용하는 데 어려움이 있어 필터링 함수에 모두 중립함수가 다시 온 되게 추가했습니다.
위와 같이 모든 필터링과 온오프가 잘 먹지만 직업 선택을 누르면 카드 데이터들이 바로 바뀌지 않는 문제가 발생했습니다.
다음엔 우선 이걸 해결해야겠습니다...٩( ′ㅂ`)و ̑̑