🐰: 개인프로젝트를 열심히 하는중에
도착한 기획팀의 요청~!
"데이터를 불러오는데 너무 오래 걸리니까
화면 분기와 데이터 오름차순, 내림차순 정렬기능 추가해주세요!"
당연히 Yes~! 이제는 두려움 보다는
어떻게 해결해낼지에 대한 기대감이 느껴지기 시작했다🤩
완성된 화면 먼저 공개 두둥-!
1. Btn1을 누르면 해당하는 열이 오름차순 정렬 -> 내림차순 정렬 -> 디폴트 정렬
2. Btn1을 눌러서 오름차순 정렬해놨다가 Btn2를 누르면 Btn2를 기준으로 오름차순 정렬
이제 코드로 알아보자~!
테이블 헤더 및 화살표 이미지 상태저장
const [selectedHeader, setSelectedHeader] = useState<number | null>(null);
const [arrowState, setArrowState] = useState<number>(0);
- 눌러진 열을 구분 할 수 있게 테이블헤더 상태를 useState를 활용하여 저장
- 오름차순, 내림차순 구분을 하게 해주는 화살표 상태 저장
헤더 클릭시 아이콘 변경
const handleHeaderClick = (index: number) => {
if (selectedHeader !== index) {
setSelectedHeader(index); // 선택된 헤더를 클릭한 인덱스로 설정
setArrowState(1); // 새로운 헤더가 선택되면 정렬 상태를 1로 초기화(오름차순)
} else {
setArrowState((prev) => (prev + 1) % 3); //동일한 헤더를 클릭하면 정렬 상태를 순환(0, 1, 2)
}
};
- selectedHeader !== index 조건이 참인 경우: 사용자가 현재 선택된 헤더가 아닌 다른 헤더를 클릭한 상황
- selectedHeader !== index 조건이 거짓인 경우: 이미 선택된 헤더를 다시 클릭한 상황 => 정렬 상태 순환하여 변경
아이콘 담기
const renderArrowIcon = () => {
switch (arrow) {
case 1:
return (
<Col style={{ position: 'absolute', bottom: 0 }}>
<RecordArrowRedUp width={10} height={10} />
</Col>
);
case 2:
return (
<Col style={{ position: 'absolute', top: 0 }}>
<RecordArrowRedDown width={10} height={10} />
</Col>
);
default:
return (
<Col>
<RecordArrowGrayUp width={10} height={10} />
<RecordArrowGrayDown width={10} height={10} />
</Col>
);
}
};
버튼 함수 호출 및 아이콘 출력
<GlobalButton onPress={handleHeaderClick}> //버튼에 함수 호출
<Row style={{ alignItems: 'center' }}>
<BoldText size={headerTextSize} align={title === 'Player' || title === 'Team' ? 'left' : 'center'} lineHeight={42} style={{ paddingRight: 3 }}>
{title}
</BoldText>
<Col style={{ position: 'relative' }} w={vw(20)}>
//정렬 아이콘
{renderArrowIcon()}
</Col>
</Row>
</GlobalButton>
데이터 sort 정렬
if (selectedHeader !== null) {
switch (selectedHeader) {
case 0:
sortedData =
arrowState === 1 ? [...data].sort((a, b) => parseFloat(a.d2) - parseFloat(b.d2)) : arrowState === 2 ? [...data].sort((a, b) => parseFloat(b.d2) - parseFloat(a.d2)) : [...data];
break;
case 1:
sortedData =
arrowState === 1 ? [...data].sort((a, b) => parseFloat(a.d3) - parseFloat(b.d3)) : arrowState === 2 ? [...data].sort((a, b) => parseFloat(b.d3) - parseFloat(a.d3)) : [...data];
break;
case 2:
sortedData =
arrowState === 1 ? [...data].sort((a, b) => parseFloat(a.d4) - parseFloat(b.d4)) : arrowState === 2 ? [...data].sort((a, b) => parseFloat(b.d4) - parseFloat(a.d4)) : [...data];
break;
case 3:
sortedData =
arrowState === 1 ? [...data].sort((a, b) => parseFloat(a.d5) - parseFloat(b.d5)) : arrowState === 2 ? [...data].sort((a, b) => parseFloat(b.d5) - parseFloat(a.d5)) : [...data];
break;
case 4:
sortedData =
arrowState === 1 ? [...data].sort((a, b) => parseFloat(a.d6) - parseFloat(b.d6)) : arrowState === 2 ? [...data].sort((a, b) => parseFloat(b.d6) - parseFloat(a.d6)) : [...data];
break;
case 5:
sortedData =
arrowState === 1 ? [...data].sort((a, b) => parseFloat(a.d7) - parseFloat(b.d7)) : arrowState === 2 ? [...data].sort((a, b) => parseFloat(b.d7) - parseFloat(a.d7)) : [...data];
break;
default:
sortedData = [...data];
}
}
[switch문 사용]
- arrowState의 상태가 1이면 오름차순 => [...data].sort((a, b) => parseFloat(a.d2) - parseFloat(b.d2))
- arrowState의 상태가 2이면 내림차순 => arrowState === 2 ? [...data].sort((a, b) => parseFloat(b.d2) - parseFloat(a.d2))
- arrowState의 상태가 1,2가 아니면 default => [...data]
* 여기서 [...data]의 의미는 data라는 변수에 담겨있는 배열의 모든 요소를 복사하여 새로운 배열을 만드는것 *