React - mini app

Enjoywater·2020년 10월 1일
2

TIL

목록 보기
26/33
post-thumbnail

Todo

연휴기간 react-hook, styled-components 연습을 위해 CRA를 사용하여 간단한 Todo app을 만들보았다. TodoGithub
API이유로 비공개 repo로 수정됨


Add

useState()를 사용하여, 초기값으로 비어있는 Object를 선언했다.
추가된 항목들의 완료 / 삭제가 원활하게 이루어져야 했기 때문에 Object를 사용했고,
항목들의 기본 구조는 { id: { id: id, text: text } }로 설정했다.

고유한 Id값react-id-generator를 사용했다.

// App.js
const [doItems, setDoItems] = useState({});

const addItems = (e) => {
    const { target, key } = e;
    if (key === "Enter" && target.value !== "") {
      const ID = nextId();
      setDoItems({
        ...doItems,
        [ID]: {
          id: ID,
          text: target.value,
        },
      });
      setValue("");
    }
  };
  1. Input이 비어있지 않음 + Enter 입력
  2. Id값 생성
  3. setDoItems()를 사용하여, 기존 doItems + 새로운 항목 추가

spread operator를 사용하여, 기존 항목들을 먼저 추가하고 새로운 항목을 추가했다.


Complete

항목을 추가할 때 지정했던 Id값을 활용해서, Do에서 삭제 후 Done에 추가했다.

// App.js
const [doneItems, setDoneItems] = useState({});

const handleComplete = (id) => {
    const tempItems = doItems;
    setDoneItems({
      ...doneItems,
      [id]: {
        id,
        text: tempItems[id].text,
      },
    });
    delete tempItems[id];
    setDoItems({ ...tempItems });
  };
  1. 기존의 Do 전체를 다른 변수(tempItems)에 할당
  2. setDoneItems()를 사용하여, 기존 doneItems + 새로운 항목 추가
  3. tempItems에서 Id를 찾아 삭제
  4. setDoItems()를 사용하여, tempItems의 항목들로 교체 (spread operator)


Delete

Complete와 마찬가지로 Id값을 활용해서, 항목들을 삭제했다.

// App.js
const handleDelete = (id, title) => {
    let tempItems;
    if (title === "Do") {
      tempItems = doItems;
      delete tempItems[id];
      setDoItems({
        ...tempItems,
      });
    } else {
      tempItems = doneItems;
      delete tempItems[id];
      setDoneItems({
        ...tempItems,
      });
    }
  };
  1. 항목 전체를 할당받을 변수(tempItems)를 미리 선언
  2. title에 따라 doItems / DoneItems 구분해서 할당
  3. tempItems에서 Id를 찾아 삭제
  4. setDoItems() / setDoneItems()를 사용하여, tempItems의 항목들로 교체 (spread operator)

Delete에서는 똑같이 생긴 코드가 반복되어서, 효율적으로 수정할 방법이 있을 것 같다.

2020.10.17 추가

삼항연산자를 사용해서 코드를 간결하게 수정했다.

const handleDelete = (id, title) => {
    const tempItems = title === "Do" ? doItems : doneItems;
    
    delete tempItems[id];

    title === "Do"
      ? setDoItems({ ...tempItems })
      : setDoneItems({ ...tempItems });
  };


styled-components

props를 사용하여 조건에 따라 효과를 다르게 줄 수 있었다.

// Items.js
const Items = ({ id, text, title, handleComplete, handleDelete }) => {
  return (
    <Container>
      <Text>{text}</Text>
      <Icon title={title}>
        {title === "Do" && (
          <Complete onClick={() => handleComplete(id)} />
        )}
        <CloseBtn title={title} onClick={() => handleDelete(id, title)} />
      </Icon>
    </Container>
  );
};


const Icon = styled.div`
  display: flex;
  justify-content: ${(props) =>
    props.title === "Do" ? "space-between" : "flex-end"};
  width: 50px;
`;

Iconprops인 title을 조건에 사용하였다.
propsstyled-components에서 사용하기 위해서는 반드시 props로 넘겨주는 값이 있어야한다.

profile
블로그 이전 👉🏻 enjoywater.tistory.com

3개의 댓글

comment-user-thumbnail
2020년 10월 4일

지렸다 갓흥수

답글 달기
comment-user-thumbnail
2020년 10월 4일

아니 이걸 혼자 만들었다구요????? 대박,,,👍🏻

1개의 답글