알파벳 리스트를 만든 후에 알파벳 클릭 시 각 알파벳에 첫 아이템으로 스크롤을 위치시켜주어야했는데
그 과정에서 받은 조언과 피드백을 토대로 정리해보려고 한다.
초기에 생가했떤 방법은 서버에서 받아오는 데이터를 각 알파벳마다 개수를 세서
컴포넌트 높이 * 브랜드 수 = 스크롤 높이
로 지정해서 처리하려고 했다
{
A : 2,
B : 1,
,,,
}
이렇게 구현하려고 하니 문제점으로는
앞전에 브랜드 카운트 된 수는 어떤방식으로 처리할지 고민이 돼서 조언을 구해 다른 방법을 추려 보았다.
우선 offsetY 값을 정할 수 있는 방법을 3가지로 추렸다.
- 데이터리스트에서 첫번째 리스트인 애들만 찾아내어서 함수를 실행시킨다.
- 서버데이터 형식 변경 [['a' , 'a' , 'a'] , ['b','b','b']]
- 최소값 비교해서 저장
2번째 방법은 서버에서 데이터 형식을 변경해서 전달해주는 방법이였고
3번째 방법은 데이터를 저장하면서 offsetY의 값을 비교해서 각 알파벳 별로 최소값인 offsetY 를 저장하는 방법이였는데
첫번째 방법으로 리스트 중 처음으로 들어오는 알파벳의 값만 저장하도록 구현하기로 결정했다.
실행되는 동작 순서로는 아래와 같이 정의했다.
- 페이지 렌더링 시 화면에 보여 줄 알파벳 리스트 만들기 (useEffect)
- 알파벳 리스트를 순회하면서
findIndex
,startWith
를 이용하여 각 알파벳의 첫index
값을 배열에 저장- Lists 의 item별로 boolean 타입의
isFirst
값을 props로 전달isFirst
이 true일 경우에 object 형태로offsetY 값
저장하기- 클릭 시 scroll되도록 설정
const getAlphabets = () => {
const alphabetAsciiCodes = Array.from(Array(26), (e, i) => i + 65);
const alphabets = alphabetAsciiCodes.map((x) => String.fromCharCode(x));
return alphabets;
};
fromCharCode
메서드로 아스키코드를 문자열로 변경해준다.const i = List?.findIndex(item => item.startsWith(a));
findIndex
주어진 판별 함수를 만족하는 배열의 첫 번째 요소에 대한 인덱스 를 반환합니다.
만족하는 요소가 없으면 -1을 반환합니다.startsWith
어떤 문자열이 특정 문자로 시작하는지 확인하여 결과를 boolean 값으로 반환
첫번째 인덱스를 저장하기 위해 아이템의 첫번째 글자를 확인하여 boolean 값을 확인하고
findIndex는 전달받은 true인 값 중 첫번째 index를 찾는다.
찾은 index 값을 배열에 저장한다.
리스트가 렌더링되면서 index 배열에서 includes
함수를 이용해
props로 isFirst
값을 전달 받는다.
getBoundingClientRect 메서드로 엘리먼트의 위치 값을 받아올 수 있다.
// offsetY 값 저장하기
const offsetY = ref?.current?.getBoundingClientRect().y;
아이템이 알파벳마다의 첫번째 아이템이고 offsetY의 값이 있다면
a: 460
과 같은 형태로 위치값을 저장한다.
useEffect(() => {
if (offsetY && isFirst) {
onOffsetYSave(name[0], offsetY);
}
}, [isFirst, name, onOffsetYSave, offsetY]);
알파벳 클릭 시 존재하는 offsetY의 값이 있다면 scrollTo를 사용하여
지정된 위치로 스크롤 시켜주도록 처리하였다.
const AlphabetClick = (alphabet: string) => {
if (!offsets[alphabet]) return;
scrollTo({
top: offsets[alphabet],
left: 0,
behavior: 'smooth',
});
};
초기에 알파벳 별로 Y의 값을 어떻게 저장할지에 대한 고민이 많아
팀원들에게 의견을 구했는데 여러가지의 방법을 알려주어서
다양하게 시도해보면서 적당한 방법을 찾은 거 같다.
스스로 찾아보려했다면 시간이 오래걸리거나 아예 알지 못했을 방법들이여서 의견내준 팀원들에게 감사하고 질문은 어렵지만 좋다는것..👀