본문 바로가기
항해99/실전 WIL | TIL

[TIL-016] React Lv2과제 모범 답안과 비교 / 숙련 주차 시험

by junvely 2023. 4. 27.

Today목표 : 4/27일 Lv2과제 모범답안과 비교 


❗todo-list 모범답안과 내 코드 비교하기

1. working zone / done zone filtering 코드

내코드

{done === true &&
          todos
            .filter((todo) => todo.isDone)
            .map((todo) => {
              return <Todo key={todo.id} todo={todo}></Todo>;
            })}
        {done === false &&
          todos
            .filter((todo) => !todo.isDone)
            .map((todo) => {
              return <Todo key={todo.id} todo={todo}></Todo>;
            })}

 

모범 답안

todos.filter((item) => {
                    return area == 'workingZoen' ? item.isDone == false : item.isDone == true
                }).map((item) => {
                    return (
                        <comm.TodoCard key={item.id}>
                            <comm.TodoTitle>{item.title}</comm.TodoTitle>
                            <comm.TodoBody>{item.body}</comm.TodoBody>
                            <comm.TodoBtns>
                                <comm.TodoBtn onClick={()=>{navigate('/details/'+item.id)}} >상세</comm.TodoBtn>
                                <comm.TodoBtn onClick={cardBtnClickEventhandle} id={item.id}>삭제</comm.TodoBtn>
                                <comm.TodoBtn onClick={cardBtnClickEventhandle} id={item.id}>{area == 'workingZoen' ? '완료' : '취소'}</comm.TodoBtn>
                            </comm.TodoBtns>
                        </comm.TodoCard>
                    )
                })

1. done 여부에 따라 두 번의 필터링을 거쳐줬는데 아래의 모범 답안처럼 filtering에서 어떤 zone인지 props으로 받아 삼항연산자로 걸러주면 한 번에 해결 가능 할 것 같다.

2. Styled-components를 styles.js 한 파일에서 관리하고 최대한 재사용할 수 있는 부분은 재사용 한다. 네이밍이 굉장히 간결하다.

3. styles를 모듈화 하여 사용할 때, 이름을 comm으로 하여 공통적으로 사용되는 컴포넌트임이 명확히 명시되어 가독성이 굉장히 깔끔했다. 또 TodoBtn, TodoTitle 이런 식으로 각각의 컴포넌트들을 가져와 사용하지 않고, comm.TodoBtn 으로 객체 하나만 가져와서 그 하위에 컴포넌트를 가져오는 방식으로 사용해서 가독성이 굉장히 좋았던 것 같다.

import * as comm from '../styles/styles'
<comm.TodoTitle>{item.title}</comm.TodoTitle>
<comm.TodoBody>{item.body}</comm.TodoBody>
<comm.TodoBtns>

 

내 코드의 개선할점 정리

가장 크게 개선하고 싶은 부분은 styled-component를 사용하는 부분이다. 자신만의 방식을 찾으면 좋을 것 같다. 내가 생각하기에는 다음과 같이 개선하면 좋을 것 같다.

1. Global 스타일은 Global.js에 둔다.

=> 프로젝트 규모가 크지 않다면 GlobalStyle.js 파일에 Shared.js의 공통 컴포넌트를 같이 관리하는 것도 좋은 것 같다. 모듈명은 Shared로.

 

2공통되는 컴포넌트일 경우 shard.js, common.js, wrap.js 에 모아 둔다. 

파일의 네이밍은 shared.js, common.js, wrap.js 정도가 좋을 것 같다. 모듈명은 shared,  comm,wrap 등이 좋겠다. 

이 컴포넌트가 공통임을 구분하기 위해 모듈을 shared 또는 공통된 네이밍으로 가져와서 하위를 불러오는 식으로 적용한다.

=>  shared.Sec / shared.Title / comm.Sec => shared가 가장 좋을 것 같다. : 이유는 comm같은 줄임말은 내 입장에서는 쉽게 연상되지만 누군가에게는 쉽게 연상되지 않을 수 있기 때문이다. shared는 파일명과 같이 사용하기에도 애매하지 않고, 직관적으로 파악하기 쉽다.

또 common에서 Colors도 관리하면 좋을 것 같다. 사용되는 컬러가 많지 않아 굳이 따로 만들지 않아도 될 것 같다. 큰 프로젝트라면 Them.js로 관리하고 Colors로 접근하는 것이 좋겠다.

 

3. 재사용할 수 있는 컴포넌트들은 최대한 shard.js 등에서 재사용 한다.

=> Titlte, Con, Body, Section, Header, Button 등

 

4. styled-components들은 많지 않기 때문에 styles.js 또는 components.js에 모아 놓고 주석처리하여 구분한다.

이때 네이밍은  StTitle, StFlexCon, StModalCon 등과 같이 St를 붙이는 것이 다른 컴포넌트와 구분되어 좋을 것 같다.

 

 

❗todo-list의 redux에서 todos와 todo를 객체의 key로 같이 관리하는 이유 

시도한점

나는 todos를 배열로 관리하고, todo는 컴포넌트 내에서 로컬 state로 관리하였는데 모범 답안에서는 todo까지 같이 전역상태로 관리하여 todos라는 객체 state 내부에서 todos키와 todo키를 같이 관리하고 있었다. 굳이 todo까지 전역에서 관리할 필요가 있을까? 싶어서 기술매니저님께 질문했었다.

 

알게된점

=> 이렇게 작은 프로젝트에서 todo를 굳이 전역에서 관리할 필요는 사실상 없으나, 우리는 redux를 처음 배우기 때문에 로컬에서 관리해도 되는 state를 전역에서도 관리할 수 있는 방법을 터득하기 위해서인 것 같다. 예를들어 detail 컴포넌트 에서 todo를 1depth 이상으로 전달해야 한다던지(props 드릴링), 컴포넌트에서 굉장히 많은 props들을 주고받고 있다던지, 프로젝트 규모가 굉장히 크거나 할 경우에는 props드릴링으로만 감당할 수 없을 정도로 정보가 많아질 수 있다. 이렇게 더 이상 컴포넌트 내의 로컬 state로 관리하기가 힘들어질 경우, 의존도가 높아질수록 todo state 하나 이더라도 전역에서 관리해야 할 때가 있는데, 이럴 경우를 대비하여 todo를 전역으로 관리하는 방법을 연습하기 위해 모범답안으로 나온 것이다.

 

 

 

❗styled-components 동적으로 스타일 변경하는 코드에 대한 리뷰

<Button
          size="large"
          name="Large Primary Button"
          width={ButtonSize.large.width}
          height={ButtonSize.large.height}
          border={ButtonSize.large.border}
          borderColor={colors.lightGreen}
          onClick={handleClickPrimaryButton}
        >
        
// Button 종류(자주 쓰이는 것들만 객체화)
export const ButtonSize = {
  small: {
    width: "100px",
    height: "40px",
  },
  medium: {
    width: "130px",
    height: "45px",
  },
  large: {
    width: "200px",
    height: "50px",
    border: "4px solid",
  },
};

// 어떤 값이 들어오든 적용 가능
export const StButtonCon = styled.div`
  width: ${(props) => props.width || ButtonSize.small.width};
  line-height: ${(props) => props.height || ButtonSize.small.height};
  height: ${(props) => props.height || ButtonSize.small.height};
  color: ${(props) => props.color || colors.black};
  background-color: ${(props) => props.bgColor || colors.white};
  border: ${(props) => props.border || "none"};
  border-color: ${(props) => props.borderColor};
  border-radius: 10px;
  margin-right: 10px;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  &:active {
    background-color: ${(props) =>
      props.bgColor === colors.lightPink
        ? colors.pink
        : props.bgColor === colors.lightGreen
        ? colors.green
        : colors.white};
  }
`;

문제상황

이와 같이 나는 큰 프로젝트에서 확장성과 재사용성을 고려해 모든 경우에 재사용할 수 있는 button 컴포넌트를 만들고 싶었다. 

 

시도한점

위 코드처럼 작성하면 어떤 케이스든 재사용이 가능하지만, 이렇게 props으로 받아 전달하는 값이 많아질 수록 코드가 길어질 수 밖에 없어 이렇게 사용하는 것이 맞는지, 아니면 부분적으로 styled-components를 사용해 small, midium, large 버튼들을 따로 만들어 관리해야 하는지 등등이 궁금했다.

 

해결방법

=> ❗결론적으로 두가지 방법 모두 사용할 수 있다. 하지만 섞어서 사용하기 보다는 한가지로 통일해 사용하는 것이 더 낫다. 객체로 굳이 값에 접근해서 전달하는 것은 굳이 필요한 부분인지는 잘 모르겠다. 어디까지 props으로 받도록 할 것인지는 현업에 가서도 계속해서 고민되는 부분이다. 두가지 다 장단점이 있는 부분이다. 내가 어떤 장점이 프로젝트에서 필요할지 판단하여 사용해야 한다.

따라서 내가 내린 결론은,

1. 모든 케이스를 다 커버 가능한 방법으로 사용하도록 리팩토링 할 경우(객체로 키에 접근해서 값을 전달하기 보다는 그냥 값을 주입)

장점 : 모든 케이스를 커버 가능하고, onClick도 button컴포넌트에서 받아 실행되게 하기만 하면 된다. 값을 주입만 하면 되기 때문에 유지 보수의 필요성이 적다. 

단점 : 코드가 길어지고 난잡해보일 수 있다.

=> 큰 프로젝트에서 유지보수를 줄이고 button컴포넌트 하나로 통일할 경우 사용하면 좋을 것 같다.

 

2. small, midium, large 버튼을 width, height 등의 골격까지 잡아 styled-components로 생성하고, bgColor나 color 등 디자인 적인 부분만 props으로 전달하여 변경가능하게 한다. onClick시 필요한 컴포넌트 내부에서 함수를 생성하여 실행되도록 하는 경우

장점 : 코드가 길어지지않고 간결하고 onClick도 필요에 따라 자유롭게 사용 가능하다.

단점 : 하지만 모든 케이스를 커버하기 힘들기 때문에 케이스가 늘어나면 계속 유지보수가 필요하다. 

=> 작은 프로젝트, 어느 정도 버튼의 케이스가 한정적이고 커버 가능한 경우 사용하면 좋을 것 같다.

// 모범 답안 중 예시 케이스 
<LargeButton addColor="green" addIcon="2193">
          Large Primary Button
</LargeButton>
<MediumButton addColor="green">Medium</MediumButton>
<SmallButton addColor="green">Small</SmallButton>
<LargeButton addColor="red" addIcon="2605">
          Large Primary Button
</LargeButton>
<MediumButton addColor="red">Medium</MediumButton>
<SmallButton addColor="red">Small</SmallButton>


// styled-components
const getButtonColor = (addColor) => {
  switch (addColor) {
    case "red":
      return "#fab1a0";
    case "green":
      return "#55efc4";
    default:
      return "";
  }
};

export const SmallButton = styled.button`
  border: 2px solid ${(props) => (props.addColor ? getButtonColor(props.addColor) : "#a8a8a8")};
  background-color: ${(props) => getButtonColor(props.addColor)};
  margin: 5px;
  padding: 5px 10px;
  font-size: 14px;
  color: ${(props) => (props.addColor === "red" ? "#d63031" : "#000000")};
`;

export const MediumButton = styled.button`
  border: 1px solid ${(props) => getButtonColor(props.addColor)};
  background-color: ${(props) => getButtonColor(props.addColor)};
  padding: 10px 20px;
  font-size: 14px;
  color: ${(props) => (props.addColor === "red" ? "#d63031" : "#000000")};
`;
export const LargeButton = styled.button`
  border: 4px solid ${(props) => getButtonColor(props.addColor)};
  padding: 12px 24px;
  font-weight: bold;
  font-size: 17px;
  color: ${(props) => (props.addColor === "red" ? "#d63031" : "#000000")};
  ${(props) =>
    props.addIcon
      ? `
    &::after {
      content: "\\${props.addIcon}";
      font-family: "Segoe UI Symbol";
      padding-left: 7px;
      color:black;
    }
  `
      : ""}
`;

알게된점

특히, 확장성이 높다고 해서 무조건 좋다고 할 수는 없다. 프로젝트 특성에 맞게, 규모에 맞게 사용하는 것이 좋다는 것을 깨달았다. 이 todo-list 프로젝트에서는 굳이 그렇게까지 확장성을 키울 필요는 없었다. 다만 나는 큰 프로젝트일 경우의 확장성과 모든 케이스의 재사용을 고려한 컴포넌트 구조를 설계하는 법을 연습하고 배우고 싶었기 때문에 그 부분을 깨달아 좋았다.

그리고 문득 내가 코드를 구상했던 1번 케이스의 경우, 이에 대한 보완점으로 tailwind를 사용할 수 있을 것 같다는 생각이 들었다. 이렇게 되면 값을 처음부터 주입하기 때문에 유지보수 시 부분적으로 값만 수정하도록 하면 된다. css속성이 많을 수록 길어지는 단점은 inline에 직접 주입하지 않고 저번에 기술 매니저님께 들었던 apply등등 여러 문법을 공부해서 사용하면 좋을 것 같다는 생각이 들었다. tailwind가 요즘 급격히 떠오르는 이유가 무엇인지는 잘 모르겠지만 오늘 처음으로 이런 부분에 대한 필요성과 차이점을 느끼게 되어 좋았고 기회가 된다면 더 공부해서 사용해 보고 싶다.

슬슬 일주일간의 styled-components와의 싸움이 어느정도 정리되어 가고 있는 것 같다.