[항해99 과제] 투두리스트 만들기 회고록

AnSuebin·2022년 12월 1일
0

들어가며
항해 99 리액트 1주차의 과제는 투두리스트 만들기였습니다. 만들면서 css부터 react까지 많은 것을 배웠고, 이를 토대로 글을 작성해보고자 합니다.

01. CSS

1. 레이아웃 최대 넓이는 1200px, 최소 넓이는 800px로 제한하고 전체화면의 가운데로 정렬해주세요

  • 레이아웃의 기본 조건이었습니다.
  • min-width / max-width를 적절히 사용하는 것이었고, 이전에 이런 방식으로 해본적이 없기 때문에 조금 해멨습니다.
  • 이부분은 모든 부분이 적용되기 떄문에 가장 큰 컴포넌트에서 적용하면 좋을 것 같다고 생각했습니다. 따라서 App.js의 container라는 가장 상위 감싸는 부분에 css를 적용했습니다.
  • min-width, max-width를 지정해주는 것과 함께 margin left와 right를 auto로 주어 중앙 정렬되게 배치하였습니다.
.container {
  min-width: 800px;
  max-width: 1200px;
  margin: 0 auto;
}

2. working 리스트가 나열됩니다.

  • 나열되는 부분의 레이아웃을 그리드로 주었습니다.
  • 여기서 포인트는 autofill, minmax였습니다.
  • 큰 컴포넌트를 감싸는 부분을 grid로 주고, grid-template-colums를 repeat(auto-fit, min(240px))로 주어 일정부분이 넘어가면 내려가도록 설정하였습니다.
  • 여기서 제 grid의 문제점은 gap을 주었음에도 불구하고 minmax를 먹이면, 셀이 붙어있다는 점이었습니다. 당시 mim사이즈를 명확하게 설정하지 않은 것에서 문제가 발생하였습니다.
  • grid 내부에 들어갈 사이즈를 다시 확인하고, min에 초점을 맞추어 작성해주었습니다.
.workingsContainer {
  display: grid;
  /* autofill공부 
  - auto-fill과 auto-fit은 
  column의 개수를 미리 정하지 않고 설정된 너비가 허용하는 한 최대한 셀을 채웁니다.
  - 
  */
  grid-template-columns: repeat(auto-fit, min(240px));
  gap: 20px;
}

.container {
  width: 200px;
  background-color: #ededed;
  padding: 20px;
  border-radius: 5px;
}
  • autofit과 autofill차이

02. 전반 구조

  • 초반에는 working리스트와 Done리스트를 따로 만들어 주었습니다. 그리고 key값을 리스트의 length로 넣었습니다.
  • 그러나 이렇게 구조를 짜면, 다른 리스트로 넘긴다는 점이 비효율적이고, 구현하면 key값이 곂치는 문제가 발생하였습니다.
  • 따라서 Done이라는 키를 불린값으로 추가하는 방법으로 변경하고, list를 하나로 합치는 작업으로 변경하였습니다.
  • 또한 키값의 중복을 피하기 위해 uuid 라이브러리를 사용하였습니다.
const Main = () => {
  const [working, setWorking] = useState([]);

  const [title, setTitle] = useState();
  const [context, setContext] = useState();

  // 인풋에서 Working 리스트로 저장하는 함수
  const addWorksHandler = () => {
    const newWork = {
      // id 값 중복을 피하기 위해 uuid 사용
      // state로 아이디 값 받아와도 괜찮음
      id: uuid(),
      title: title,
      context: context,
      done: false,
    };
    setWorking([...working, newWork]);
    setTitle("");
    setContext("");
  };

03. done으로 변경할 때

  • 이 부분을 이전에는 무척 비효율 적이게 구현하였습니다.
  • done으로 가져오고 싶은 값만 빼는 filter를 사용해주고
  • 가져오고 싶은 값을 filter로 해서, 맵으로 done 값을 true로 변경해주었습니다.
  • 마지막에 구조분해로 각각 working자리에 넣어주었습니다.
    const filtering = working.filter((work) => {
      return work.id !== doneid;
    });
    const fix = working
      .filter((work) => {
        return work.id === doneid;
      })
      .map((work) => {
        return {
          id: work.id,
          title: work.title,
          context: work.context,
          done: true,
        };
      });

    setWorking([...filtering, ...fix]);
  • 그러나 findIndex에서 찾아 그부분만 변경해주는 방법을 동료로 부터 알게되었습니다.
  • 같은 아이디 값의 인덱스를 받아온 후
  • 그 인덱스 의 done 값을 true로 설정해줍니다.
  • 그리고 구조분해로 setWorking값을 넣어줍니다.
const index = working.findIndex((todo) => todo.id === doneid);
	working[index].done = true;
	setWorking([...working]);

04. input을 submit하면 비어있게 처리

  • submit을 한 후 빈값으로 처리해주는 과정에서 에러가 떴습니다.
  • 빈값이면 안된다는 에러였습니다.
  const [title, setTitle] = useState();
  const [context, setContext] = useState();

  // 인풋에서 Working 리스트로 저장하는 함수
  const addWorksHandler = () => {
    const newWork = {
      // id 값 중복을 피하기 위해 uuid 사용
      // state로 아이디 값 받아와도 괜찮음
      id: uuid(),
      title: title,
      context: context,
      done: false,
    };
    setWorking([...working, newWork]);
    // 추가 후 빈값으로 처리하는 코드
    setTitle("");
    setContext("");
  };
  • 에러에 대해 검색해보니, vlue값이 빈값인것도 함께 설정해주어야한다고 되어있었습니다.
          // 추가 후 빈값으로 설정하기 위해서
          // 콘솔에러가 뜨는데 처음 타이틀에 아무것도 없을 때는 '' 빈값으로
          value={title || ""}

04. List가 빈값일 때 처리

  • 사실 구현할 때는 잊었었는데 꼭 필요한 부분이여서 기입합니다.
  • 리스트에는 &&로 있을 때 맵을 돌린다는 것을 설정해주었어야 했습니다.
{WorkandDonelist &&
        WorkandDonelist.map((work) => {

05. 마치며

투두리스트는 수백번 해봤다 생각했는데, 생각보다 어려운 부분과 몰랐던 부분이 많았습니다. 세부적인 부분을 단순히 가져오는 것이 아닌, 스스로 생각해보는 시간을 가져야겠습니다.

06. 추가 공부

다른 분이 짠 코드를 보니, input을 받는 형태가 달랐습니다. 신선한 형태였고, 이 부분을 추가로 공부 후 정리해보고자 아래 내용을 작성해봅니다.

  • 아래와 같이 작성하면, 여러 input창이 있더라도 state를 하나만 관리 할 수 있습니다.
  • 특이한 점은 event.target을 콘솔로 치면
    태그의 형태로 뜨는데, 객체로 속성을 받아와 구조분해할당으로 id값과 value값을 가져올 수 있다는 점입니다.
  • 이를 활용해 input값을 1개의 state로 관리할 수 있습니다.
  const [todos, setTodos] = useState({ title: "", content: "" });

  const onChangeInputHandler = (event) => {
    const { value, id } = event.target;
    setTodos({ ...todos, [id]: value });
  };

  console.log(todos);
  return (
    <>
      <input
        type="text"
        value={todos.title}
        id="title"
        onChange={onChangeInputHandler}
      />
      <input
        type="text"
        value={todos.content}
        id="content"
        onChange={onChangeInputHandler}
      />
    </>
  );

참고
그리드 내용 참고 링크
추가 공부관련 참고 링크

profile
고객에게 명료한 의미를 전달하고, 명료한 코드를 통해 생산성 향상에 기여하고자 노력합니다.

0개의 댓글