[React Hooks] 버그 수정

박은지·2022년 2월 20일
0

Todo Application

목록 보기
5/7

버그 발견

새로 추가한 Todo에 대한 완료/미완료 상태 표현이 작동하지 않는 버그를 발견했다.

원인을 찾아보니...TodoCode의 형식과 타입이 잘못되었던 것 ㅠㅠ
원래 todoCode는 YYYYMMDDN 형식이고 문자열 타입이지만, 새로 추가된 할 일의 todoCode는 날짜 없이 그냥 새로운 todo의 순서를 나타내는 숫자 타입이다.

Todo Application 수정

[1] initialTodoData.js

module.exports = [
  {
    todoCode: '202202171', 
    date: 20220217,
    title: 'Todo 20220217-1', 
    contents: 'Todo 1 Todo 1 Todo 1', 
    done: true, 
    edit: false
  },
  
  . . .
  
  {
    todoCode: '202202213', 
    date: 20220221,
    title: 'Todo 20220221-3', 
    contents: 'Todo 3 Todo 3 Todo 3', 
    done: false, 
    edit: false
  },
];
  

[2] server.js

// Express / port / cors & body-parser --------------------------------- //
const express = require('express');
const app = express();
const port = 4000;
const cors = require('cors');
const bodyParser = require('body-parser');

// InitialTodoData ------------------------------------------------------ //
const initialTodoData = require('../src/InitialTodoData.js');



app.use(bodyParser.urlencoded({ extended: false }));
app.use(cors());
app.use(bodyParser.json());
// app.use(express.json()); 

// API ------------------------------------------------------------------ //
// GET 
/// 모든 Todos 조회
app.get('/initialtodos', (req, res) => {
  res.send(initialTodoData);
});

/// 특정 날짜에 해당하는 Todos 조회
app.get('/initialtodos/:dailyKey', (req, res) => {
  const {dailyKey} =  req.params;
  res.send(initialTodoData.filter(todo => todo.date === Number(dailyKey)));
});


// listen() ------------------------------------------------------------- //
app.listen(port, () => {
  console.log(`Server is listening on port ${port}`);
});

[3] App.js

import React, { useEffect, useState } from 'react';
import './App.css';

// Custom Hook
import useFetch from './useFetch.js';

// Components 
import Header from './components/Header.jsx';
import Form from './components/Form.jsx';
import List from './components/List.jsx';

// Context API
export const TodoContext = React.createContext();

// App Component
function App() {

  const [todos, setTodos] = useState([]);  // todos

  // Today
  const now = new Date();
  const dailyKey = Number(new Date(now.setDate(now.getDate()+1)).toISOString().substring(0,10).replace(/-/g,'')); // YYYYMMDD (number)
  // const dailyKey = Number(new Date(now.setDate(now.getDate()+when)).toISOString().substring(0,10).replace(/-/g,''));
  
  const loading = useFetch(setTodos, `http://localhost:4000/initialtodos/${dailyKey}`);
  
  const addTodo = (newTodo) => { // addTodo : 새로운 todo를 배열에 추가하는 함수
    setTodos([...todos, {'todoCode': `${dailyKey}${todos.length + 1}`, 'date': dailyKey, 'title': newTodo, 'contents': '', done: false, edit: false}]);
  }

  // changeTodoDone
  const changeTodoDone = (todoCode) => {
    const updateTodos = todos.map(todo => {
      if(todo.todoCode === todoCode) {
        if(todo.done === true) todo.done = false;
        else todo.done = true;
      }
      return todo;
    })
    setTodos(updateTodos);
  }

  useEffect(() => {
    console.log("새로운 내용이 추가되었습니다.", todos);
  }, [todos]);


  return(

    <TodoContext.Provider value={{todos, addTodo, loading, changeTodoDone}}>
      <Header />
      <Form />
      <List />
    </TodoContext.Provider>

  );
}

export default App;

[4] Header

Header.js

import React, { useContext } from 'react';
import './Header.css';
import { TodoContext } from '../App.js';

function Header() {

  // useContext를 통해 todos 정보 접근
  const {todos} = useContext(TodoContext);

  // 미완료 상태(done: false)인 todo들의 배열
  const undoneTasks = todos.filter(todo => todo.done === false);

  // 날짜, 요일
  const now = new Date();
  // const today = new Date(now.setDate(now.getDate() + when));
  const today = new Date(now.setDate(now.getDate()));
  const dateString = today.toLocaleDateString('ko-KR', {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
  });
  const dayName = today.toLocaleDateString('ko-KR', {
    weekday: 'long',
  });

  return(
    <>
      <h1 className='date'>{dateString}</h1>
      <div className='dayname'>{dayName}</div>
      <div className='countInfo'>{`남은 할 일 : ${undoneTasks.length}`}</div>
    </>    
  );
}

export default Header;

Header.css

.dayname {
  padding-bottom: 1rem;
  margin-bottom: 1.5rem;
  border-bottom: 1px solid #eee;
}
.countInfo {
  margin-bottom: 1rem;
}


0개의 댓글