TIL 12.14

새양말·2022년 12월 14일
0

내일배움캠프TIL

목록 보기
28/74
post-thumbnail

todo-list

리액트 환경 세팅(CRA)
컴포넌트 분리 - Header, Input, TodoList, Footer
initialState를 3개 부여(각각의 todo는 title, contents, isDone, id 프로퍼티를 가짐)
todos state를 만들고, 화면에 출력
Input 컴포넌트 안에 input 태그 2개 및 button 태그 하나 -> form 태그를 이용하여 구현

id값으로 uuid값을 쓰는 이유

todos의 length로 id값을 부여하면 crud를 하면서 todos의 length값이 달라지기 때문에 데이터가 뒤엉켜 에러가 발생할 수 있다.
따라서 새로고침할 때마다 고유한 값을 가지는 uuid를 부여하는 것이 에러를 줄일 수 있다.

만드는 순서

  1. 최상위 컴포넌트 App()의 return()부분부터 작성한다.
    header - main - footer 태그를 먼저 잡고
    main 안에 필요한 요소 ( 여기선 제목,내용 입력창과 입력된 창을 출력하는 부분이 필요 ) 를 구성해본다.
    그리고 컴포넌트로 분리한다.
return (
    <div>
      {/* <header>헤더입니다.</header> */}
      <Header>헤더입니다.</Header>
      <main
        style={{
          padding: '20px',
          backgroundColor: '#caedd3',
        }}
      >
        {/* 인풋창2개 추가버튼 */}
        <Input setTodos={setTodos} />
        {/* initialState 출력창 - 진행, 완료 2파트*/}
        {/* 진행 isActive  */}
        <TodoList isActive={true} setTodos={setTodos} todos={todos} />
        <TodoList isActive={false} setTodos={setTodos} todos={todos} />
      </main>
      {/* <footer>푸터입니다.</footer> */}
      <Footer>푸터입니다.</Footer>
    </div>
  );

사용한 컴포넌트

  1. TodoList 컴포넌트에서 데이터 출력 부분을 만든다.
    App()에서 선언해준 initialState를 출력해본다.
function TodoList({ isActive, setTodos, todos }) {
  return (
    <div>
      <h3>{isActive ? '진행중' : '완료'}</h3>
      {/* todos 출력 - 하나씩 뽑아서 진행/ 완료 분리해서 출력 */}
      {todos
        .filter((item) => item.isDone === !isActive)
        .map((item) => {
          return (
            <div key={item.id}>
              <h5>{item.title}</h5>
              <p>{item.contents}</p>
              <button>{isActive ? '완료' : '취소'}</button>
              <button>삭제</button>
            </div>
          );
        })}
    </div>
  );
}

filter, map 함수에 대해 잘 알아야 중첩사용해도 헷갈리지 않는다.

  1. 입력창을 만든다.
    역시 return부분부터 만들어서 필요한 함수가 무엇인지 정해야 길을 잃지 않는다.
    받아와야할 props들도 잘 생각해야 한다.
function Input({ setTodos }) {
  const [title, setTitle] = useState('');
  const [contents, setContents] = useState('');

  const handleSubmit = (event) => {
    event.preventDefault();

	// 입력창 초기화해준다.
    setTitle('');
    setContents('');
	// 사용자의 행동을 제어해준다.
    if (title === '') {
      alert('제목을 입력하세요');
      return;
    }
    if (contents === '') {
      alert('내용을 입력하세요');
      return;
    }

    // newTodo 만들어서 setTodos에 같이 넣어준다
    const newTodo = {
      title,
      contents,
      isDone: false,
      id: uuidv4(),
    };

    setTodos((prev) => {
      return [...prev, newTodo];
    });
  };
  const handleTitleChange = (event) => {
    setTitle(event.target.value);
  };
  const handleContentsChange = (event) => {
    setContents(event.target.value);
  };

  return (
    <div>
      <section>
        <form onSubmit={handleSubmit}>
          제목: <input value={title} onChange={handleTitleChange} />
          내용: <input value={contents} onChange={handleContentsChange} />
          <button>추가</button>
        </form>
      </section>
    </div>
  );
}

내일 이어서 crud 중에서 나머지 업데이트, 삭제를 추가해주겠다.

profile
매번 기합넣는 양말

0개의 댓글