토이프로젝트 Tre 3일차에 API 설계를 하려고 했지만 서버 부분의 개발 경험이 많이 부족해서 지금 구조를 미리 구성하여도 추후에 수정이 매우 많이 될 것 같아서 프론트 개발이 완료되고 나서 API 설계 후 백엔드 구현을 하기로 계획을 수정하여 3일차 4일차는 프론트 구현을 시작하였다.
프론트 기술 스택은 아래와 같이 정하였다.
구현 중 계획 화면에서 예정 계획과 지난 계획 탭을 Ant design의 Card tab을 이용하려고 했으나 크기를 직접 수정이 어려워서 직접 만들어보기로 하였다.
UI는 styled-component를 이용해서 원하는 크기와 스타일로 만들었지만 2개의 탭 중 현재 탭 이외의 탭을 클릭했을 때만 이벤트가 발생하여 내용을 표시하고 싶었는데 구현이 어려워 구글링을 통해 여러 글을 참고하여 구현을 완료하였다.
우선 일정 계획과 지난 계획을 나타내기 위해 2개의 탭이 필요하여 배열로 선언하여 map함수를 통해 표현하여 코드 수를 줄이고 효율적으로 작성하였다.
tabContents는 각 탭을 클릭시 보여줄 컴포넌트를 키 값과 컴포넌트 형태인 객체로 선언하였다.
const tabTitle = ["일정 계획", "지난 계획"];
const tabContents = {
0: <FuturePlanComponent />,
1: <PastPlanComponent />,
};
그리고 직접 styled-components를 이용하여 탭의 스타일 작성하고 props를 이용하여 클릭시와 클릭이 안되어 있는 탭의 구별하기 위해 배경색을 다르게 표현하였다.
const CardTab = styled.div`
position: relative;
width: 300px;
height: 100%;
border: 1px solid #f3f3f3;
border-radius: 15px 0 0 0;
cursor: pointer;
background-color: #fffcf1;
&:hover {
color: #3fbdff;
}
${(props) =>
props.active &&
css`
background-color: #fff;
&:hover {
color: #000;
}
`};
`;
active props의 값은 ture or false 값을 가지며 tabTitle의 인덱스 번호의 값과 activeState값을 비교하여 결정한다.
탭 클릭 시에는 onClick 이벤트가 발생하여 activeState 값이 바뀌고 active 값을 판단하여 탭이 바뀌게 된다.
const ScheduleLayout = () => {
const [activeState, setActiveState] = useState(0);
const onTabClicked = useCallback((key) => {
setActiveState(key);
}, []);
return (
<StyledBackground>
<FrameStyled>
<TabsContainer>
{tabTitle.map((str, idx) => {
return (
<CardTab
active={activeState === idx}
key={idx}
onClick={() => onTabClicked(idx)}
>
<TabText>{str}</TabText>
</CardTab>
);
})}
</TabsContainer>
{tabContents[activeState]}
</FrameStyled>
</StyledBackground>
);
};
원래는 CardTab 태그의 onClick 부분을 onTabClicked(idx)로 작성했더니 Too many re-renders. React limits the number of renders to prevent an infinite loop.
이러한 오류가 발생하였다.
간단히 해석해보면 리렌더링이 너무 많으며 무한 루프를 방지하기 위해 제한하였다. 라는 의미로 오류 코드 그대로 구글링을 하여 해결하였다.
위의 코드와 같이 arrow funtion을 이용하여 작성해야 리렌더링을 방지할 수 있다.
참고한 자료
https://velog.io/@lilyoh/React-menu-tab-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0
https://velog.io/@ryuinkyoto/wecode-%EB%A6%AC%EC%95%A1%ED%8A%B8%EB%A1%9C-Menu-Tab-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0
https://velog.io/@ppby/Error