확장성 높은 tabButton을 만들어보자.
조건
1. firstButton과 secondButton을 누르면 각각에 알맞은 데이터가 보여져야한다.
2. thirdbutton, fourth button 등이 추가 될 가능성을 고려해서 만들어야한다.
구현 방법
1. 변경되는 탭 모드를 저장할 state를 만들어준다.
2. 각 탭 버튼에 고유한 값을 할당하고, 해당 값을 이벤트 핸들러에 전달한다.
3. 이벤트 핸들러에서 전달받은 값에 따라 현재 활성화된 탭을 업데이트한다.
4. 활성화된 탭에 따라 적절한 데이터를 렌더링한다.
1. 부모컴포넌트에 탭 모드를 저장할 state와 탭 모드 변경시 실행되는 함수를 만들어준다.
부모컴포넌트.tsx
//탭모드를 저장한 state/ 초기값은 firstBtn으로 설정
const [nowActivatedTabValue, setNowActivatedTabValue] = useState("firstBtn");
//탭모드 변경시 실행되는 함수
const nowActivatedTabValueHandler = (inputValue: string) => {
setNowActivatedTabValue(inputValue);
};
탭이 변경될 때마다 실행되어 현재 활성화된 탭의 값을 업데이트해준다.
이렇게 함으로써 현재 활성화된 탭에 따라 적절한 동작을 수행할 수 있다.
2. 탭 버튼 컴포넌트를 만들어준다.
listSwitchBtn.tsx
const ListSwitchBtn = ({
//부모에서 만든 function, state 전달
nowActivatedTabValueHandler,
nowActivatedTabValue,
}: any) => {
return (
<div className="switchBtn flex_center">
<Button
className={nowActivatedTabValue === "firstBtn" ? "btnL" : "btnR"}
value="firstBtn"
onClick={(e) => {
nowActivatedTabValueHandler((e.target as HTMLButtonElement).value);
}} //e.target.value를 사용하면 typeError발생
>
탭 버튼1
</Button>
<Button
className={nowActivatedTabValue === "secondBtn" ? "btnL" : "btnR"}
value="secondBtn"
onClick={(e) => {
nowActivatedTabValueHandler((e.target as HTMLButtonElement).value);
}} //e.target.value를 사용하면 typeError발생
>
탭 버튼2
</Button>
</div>
);
};
3. 버튼을 만들고, value에 값을 지정해준다.
이렇게 하는 이유는 버튼을 클릭했을 때 이벤트 핸들러 함수인 nowActivatedTabValueHandler에
전달할 구분자를 만들어주기 위해서이다.
코드에서 보면, 각 버튼의 onClick 이벤트에서 nowActivatedTabValueHandler 함수를 호출할 때,
버튼의 value 값을 인자로 전달하고 있다. 이렇게 전달된 값은 함수 내에서 다양하게 사용될 수 있다.
예를 들어, setNowActivatedTabValue(inputValue)를 통해 현재 활성화된 탭의 값을 업데이트하거나, nowActivatedTabValue === "firstBtn"과 같은 조건문에서 현재 활성화된 탭의 스타일을 지정해줄 수 있다.
따라서 버튼에 value를 넣음으로써, 개별 버튼을 클릭했을 때 어떤 버튼이 클릭되었는지 구분시켜주고,
적절한 동작을 수행할 수 있도록 할 수 있다.
- setNowActivatedTabValue(inputValue): 현재 활성화된 탭의 값
4. tabButton에 API를 연동하는 방법
API로 불러온 데이터를 탭 버튼과 연결하기 위해서는 API를 받아오는 함수를 만들고
이를 기존의 nowActivatedTabValueHandler 함수에 넣어주면 된다.
- 탭 버튼이 클릭되면 API 요청이 되도록 수정해준다.
fetchList 함수
const fetchList = async (pageNum: number) => {
try {
// 현재 활성화된 탭에 따라 API 요청 URL을 생성해준다.
let select = "";
switch (nowActivatedTabValue) {
case "firstBtn":
select = "";
break;
case "secondBtn":
select = "/com";
break;
}
// API를 요청한다.
const response = await fetch(
`https://API 주소`
);
// 응답을 JSON 형태로 변환한다.
const data = await response.json();
// 응답에 오류가 있다면, 알림을 표시하고 함수종료
if (data.responseCode !== undefined) {
alert(data.responseMessage);
return;
}
// 가져온 데이터를 state에 저장한다.
setListData(data.counselingList);
// 쿼리파라미터
history.push({
search: `?page=${pageNum}&pageSize=${
pageSize * pageNum
}&_criterion=${criterionState[currentCriterionValue]}`,
});
} catch (error) {
console.error('Error fetching data:', error);
}
};
수정된 nowActivatedTabValueHandler 함수
const nowActivatedTabValueHandler = (inputValue: string) => {
setNowActivatedTabValue(inputValue);
// 탭 버튼이 클릭되면 fetchApplicationList 함수를 호출하며, 현재 페이지 번호가 전달된다.
fetchList(currentPageNumber);
};
5. thirdButton 을 추가하고 싶을때는 어떻게 할까?
listSwitchBtn.tsx 컴포넌트와 fetchList 함수를 수정해주면 된다.
listSwitchBtn.tsx
<Button
className={nowActivatedTabValue === "thirdBtn" ? "btnL" : "btnR"}
value="thirdBtn"
onClick={(e) => {
nowActivatedTabValueHandler((e.target as HTMLButtonElement).value);
}}
>
탭 버튼3
</Button>
const fetchList = async (pageNum: number) => {
try {
let select = "";
switch (nowActivatedTabValue) {
case "firstBtn":
select = "";
break;
case "secondBtn":
select = "/com";
break;
case "thirdBtn":
select = "/yourPath";
break;
}
// 나머지 코드...
} catch (error) {
console.error('Error fetching data:', error);
}
};
탭 버튼 마다 원하는 API를 불러오는 예제📍
'개발이야기 > React.js' 카테고리의 다른 글
React에서 map()함수 사용시 return 문의 필요성 (0) | 2023.05.03 |
---|---|
React에서 useEffect를 활용한 상태 값 변화 확인 방법 (0) | 2023.04.27 |
[React] 하위 Route 만들기 (0) | 2022.06.23 |
[React] Router (0) | 2022.06.23 |
[React] NavLink (0) | 2022.06.22 |