todoList 만들기 ② (react)

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

📝 TodoList 2

✅ validation

💥 input 값이 비었을 때도 todo가 추가되는 문제
input에 required 속성을 줄 수도 있었지만 메시지로 띄우고 싶어서 useState를 하나 더 만들었다

💡
1. 기본값은 false, input 값이 비었을 때는 true로 바꾸고
정상적으로 값이 들어갔다면 false로 다시 돌아감
(다시 false로 돌아가지 않으면 한 번 경고메시지가 뜨고 나면 정상적으로 입력해도 다시 없어지지 않음)
2. AddTodo 컴포넌트에 props으로 validationMsg 내려주고 값이 true 일 때만 경고메시지가 나타나도록 함

const [validationMsg, setValidationMsg] = useState(false);

// todo 추가 함수
  const submitHandler = (e) => {
    e.preventDefault();
    // 값이 비었을 때
    if (inputs.title.length === 0 || inputs.body.length === 0) {
      setValidationMsg(true);
      return;
    }
    // 값이 있을 때
    const newTodo = {
      id: uuidv4(),
      title: inputs.title,
      body: inputs.body,
      isDone: false,
    };
    setTodos([newTodo, ...todos]);
    setInputs({
      title: '',
      body: '',
    });
    setValidationMsg(false);
  };
<span className='error-msg'>
   {validationMsg ? '빈 칸을 채워주세요' : null}
</span>

✅ 삭제시 확인메시지 띄우기

💥 삭제버튼을 누르면 바로 삭제됨
💡 confirm 창을 띄워 확인을 눌렀을 때만 삭제되도록 수정
window.confirm 을 해줘야 함(그냥 confirm 으로 하면 오류)

  const deleteTodo = (id) => {
    if (window.confirm('정말 삭제하시겠습니까?')) {
      setTodos((todos) => todos.filter((todo) => todo.id !== id));
    }
  };

✅ progress bar 만들기

목표 달성도를 bar 형태로 보여주기

💡

1. ProgressBar 컴포넌트 만들기

2. 달성도를 측정할 함수 만들기 (percentTodo)

2-1. todos 배열을 돌면서 완료한 todo만 골라내기

2-2. 전체 배열에서 완료한 todo를 나누고 100을 곱해 percent 구하고 소수점 둘째자리까지 표시

2-3. percent가 NaN이라면 0을 리턴 (빈 배열일때)

2-4. 아니라면 percent 리턴 후 ProgressBar 에 props 내려주기

	// App.js
  const percentTodo = () => {
    const isDoneTodo = todos.filter((todo) => todo.isDone === true);
    const percent = ((isDoneTodo.length / todos.length) * 100).toFixed(2);
    if (isNaN(percent)) {
      return 0;
    }
    return percent;
  };

3. UI 만들기

3-1. 받아온 props만큼 width 값 주기

3-2. 모두 달성하면 축하합니다, 아니라면 달성도를 텍스트로 보여줌

(100으로 하면 '축하합니다'가 뜨지 않아서 99.99로 변경)
(chatGPT 답변: 소수점 이하를 반올림한 결과로 인해 percent 값이 100이 아니라 다소 작을 수 있습니다.)

// ProgressBar.jsx
const ProgressBar = ({ percentTodo }) => {
  const percent = percentTodo();
  return (
    <div className='progress-bar'>
      {percent >= 99.99 ? `축하합니다 👏` : `달성도 ${percent} %`}
      <div className='progress' style={{ width: `${percent}%` }}></div>
    </div>
  );
};
/* css */
.progress-bar {
  background-color: #eee;
  border-radius: 50px;
  margin-top: 10px;
  width: 100%;
  height: 30px;
  line-height: 30px;
  color: #000;
  text-align: center;
  overflow: hidden;
  position: relative;
}

.progress {
  position: absolute;
  top: 0;
  left: 0;
  width: 10%;
  height: 30px;
  background-color: #881ad1;
  opacity: 0.5;
}
  1. percentTodo 함수 리팩토링
const percentTodo = () => {
  const todosPercent = todos.filter((todo) => todo.isDone).length;
  return todos.length ? ((todosPercent / todos.length) * 100).toFixed(2) : 0;
};

✅ 모두 지우기

ClearAll 컴포넌트 만들기
모두 지우기 버튼 만들고 setTodos([]) 로 todo 모두 지우기

  const clearTodo = () => {
    setTodos([]);
  };
profile
호기심 많은 귀차니즘의 공부 일기

0개의 댓글