todoList 만들기 ① (react)

Jtiiin:K·2023년 11월 3일
0
post-thumbnail

📝 TodoList

✅ CRA 설치

npx create-react-app 프로젝트명

✅ 기본 틀 잡기

html 구조 잡기
더미 데이터 만들어서 최종적으로 만들려는 ui 기본 틀 구현
데이터의 상태(todos)를 관리해야하기 때문에 useState() 사용
(여러 개의 todo를 담기 위해 배열형태 [{}, {}, {}, ...])
각 todo에는 id, title, body, isDone이 들어감
const [todos, setTodos] = useState([])

✅ ui 구현

todos.map으로 todo를 화면에 그려줌
todo.isDone 상태에 따라 조건부 렌더링

      <section>
        <h2>Working... 🔥</h2>
        {todos.map((todo) => {
          if (!todo.isDone) {
            return (
              <div key={todo.id}>
                <h3>{todo.title}</h3>
                <p>{todo.body}</p>
                <button>삭제하기</button>
                <button>완료</button>
              </div>
            );
          }
        })}
      </section>

	<section>
        <h2>Done..! 🎉</h2>
        {todos.map((todo) => {
          if (todo.isDone) {
            return (
              <div key={todo.id}>
                <h3>{todo.title}</h3>
                <p>{todo.body}</p>
                <button>삭제하기</button>
                <button>완료</button>
              </div>
            );
          }
        })}
      </section>

✅ input 연결하기

사용자가 입력한 input값을 데이터로 관리(inputs)하기 위해 useState() 사용
input 여러 개를 함께 관리하기 위해 name을 붙이고 onChange 함수를 연결

  const [inputs, setInputs] = useState({
    title: '',
    body: '',
  });

// e.target.name 이 inputs의 key 값으로 사용 => [] 표기법 사용
  const inputChangeHandler = (e) => {
    setInputs({
      ...inputs,
      [e.target.name]: e.target.value,
    });
  };
<input
   type='text'
   name='title'
   value={inputs.title}
   onChange={inputChangeHandler}
/>

✅ todo 추가하기

form 에 onsubmit 함수를 연결
브라우저 새로고침 막아주기 (e.preventDefault())
새로운 todo 객체(newTodo) 만들어서 setTodos()로 todos 업데이트 => 불변성
추가 후 input 값 비워주기

  const submitHandler = (e) => {
    e.preventDefault();
    const newTodo = {
      id: todos.length,
      title: inputs.title,
      body: inputs.body,
      isDone: false,
    };
    setTodos([...todos, newTodo]);
    setInputs({
      title: '',
      body: '',
    });
  };

✅ todo 삭제하기

삭제버튼에 onClick 함수 연결
id를 받아와서 클릭된 todo의 id와 받아온 id가 일치하지 않는 것만 filter

  const deleteTodo = (id) => {
    setTodos(todos.filter((todo) => todo.id !== id));
  };

✅ todo 완료/취소하기

완료버튼에 onClick 함수 연결
id를 받아와서 클릭된 todo의 id와 받아온 id가 일치하면
todo.isDone의 상태를 바꾼 다음 return

  const toggleTodo = (id) => {
    setTodos(
      todos.map((todo) => {
        if (todo.id === id) {
          todo.isDone = !todo.isDone;
        }
        return todo;
      })
    );
  };

✅ 고유한 id 사용하기 (uuid)

💥 todo를 추가하는 과정에서 id값을 todos.length로 줬는데
삭제하고 새로운 todo를 추가할 때 id가 중복되는 문제가 생김
💡 중복되지 않는 고유한 id 필요 => uuid 라이브러리
(여러 버전이 있는데 버전이 높아질 수록 견고한 고유 값을 제공함)

  • 설치
    npm install uuid / yarn add uuid

  • 사용법
    import {v4 as uuidv4} from 'uuid'
    const id = uuidv4()
    => import 후 사용하고자 하는 곳에서 함수처럼 사용

✅ 컴포넌트 분리하기

AddTodo

form 부분을 컴포넌트로 분리

TodoList

todo가 렌더링 되는 부분을 크게 분리하고 그 안에 TodoItem을 또 분리

✔ 진행중 / 완료 section에 중복되는 코드가 많아서 컴포넌트로 분리 시도
💥1. 서로 title이 다르고 isDone 상태에 따라 분리해서 보여줘야 함
💥2. 컴포넌트안에 title을 그대로 가져오려고 했지만 데이터가 없으면 title 마저 보이지 않음
💡 title과 isDone 이라는 props를 추가하고 isDone이 true/false일 때를 나누어
todos를 가공해 나온 결과인 filteredTodos를 map으로 돌면서 렌더링

// app.js
      <TodoList
        todos={todos}
        deleteTodo={deleteTodo}
        toggleTodo={toggleTodo}
        title='Working... 🔥'
        isDone={false}
      />

      <TodoList
        todos={todos}
        deleteTodo={deleteTodo}
        toggleTodo={toggleTodo}
        title='Done...! 🎉'
        isDone={true}
      />
// todoList.jsx
const TodoList = ({ todos, deleteTodo, toggleTodo, title, isDone }) => {
  const filteredTodos = isDone
    ? todos.filter((todo) => todo.isDone)
    : todos.filter((todo) => !todo.isDone);
  return (
    <section>
      <h2>{title}</h2>
      {filteredTodos.map((todo) => (
        <TodoItem
          key={todo.id}
          todo={todo}
          deleteTodo={deleteTodo}
          toggleTodo={toggleTodo}
        />
      ))}
    </section>
  );
};

TodoItem

각각의 todo 를 컴포넌트로 분리

✅ CSS 적용

요구사항에 있는 최대, 최소 넓이 적용
추후 스타일링 하기 쉽도록 (구역을 볼 수 있게) 색상만 일단 넣음 (디자인테러😫)

profile
호기심 많은 귀차니즘의 공부 일기

0개의 댓글