TodoList 만들기 3
2024. 7. 18. 18:09ㆍSpringboot-React
TodoList,js
import React, {useState, useContext} from "react";
import TodoListContext from "./TodoListContext.js";
const TodoList = () => {
const {todoList, setTodoList, loginMember} = useContext(TodoListContext);
const [inputTodo, setInputTodo] = useState('');
let keyIndex = 0;
//할 일 추가 버튼 기능 설정
const addTodo = () => {
//할 일이 입력되지 않았다면 입력해달라는 알림창
if(inputTodo.trim().length === 0){
alert('할 일을 입력해주세요');
return;
}
fetch("/todo", {//TodoController에서 /todo라는 url 주소에서 db에 값 추가
method : "post",
headers : {'Content-Type' : 'application/json'},
body : JSON.stringify({
title : inputTodo,
todoMemberNo: loginMember.todoMemberNo
})
})
.then(response => response.text())
.then(todoNo => {
if(Number(todoNo) === 0){
return;
}
//기존 todoList + 새로 추가된 todo를 이용해 새 배열 생성, todoList에 대입
const newTodo = {
todoNo : todoNo,
title:inputTodo,
isDone: 'Y',
todoMemberNo: loginMember.todoMemberNo
};
//기존 todoList + newTodo를 이용해 새로운 할 일 만들기
const newTodoList = [...todoList, newTodo];
//todoList에 대입
setTodoList(newTodoList);
setInputTodo('');
})
//문제가 생기면 console창에서 보여주기
.catch(
e => console.log(e)
)
}
//할 일을 완료하면 X버튼, 완료하지 못하면 O버튼 표시
//특정 할 일의 번호를 받아 특정 할 일만 수정
const updateTodo = (todo, index) => {
console.log("todo : " + todo);
console.log("index : " + index);
fetch("/todo",{
method: "put",
//Content-Type = controller로 값을 전달할 때 어떤 파일(이미지, 동영상, 글자 등)인지 전달하는 공간
headers:{'Content-Type' : 'application/json'},
//JSON으로 된 파일을 문자로 변경, 글자 취급으로 사용
body: JSON.stringify({
todoNo: todo.todoNo,
//할 일 완료 여부가 O로 되어있으면 X로 변경
//X로 되어 있으면 O로 변경
isDone: todo.isDone === 'Y' ? 'N' : 'Y'
})
})
.then(response => response.text())
.then(result => {
//응답에 대한 결과가 없으면 업데이트 실패했음을 알려주기
if(result === '0'){
alert('할 일 수정에 실패했습니다')
return;
}
//수정 성공 시 todoList 값을 변경해서 새로고침
//기존 할 일 목록(todoList)를 복사해서 새로 추가된 할 일을 더한 다음
//해로운 할 일로 업데이트
const newTodoList = [...todoList];
//index 번호의 태그 값을 O or X로 변경
newTodoList[index].isDone = newTodoList[index].isDone === 'Y' ? 'N' : 'Y';
setTodoList(newTodoList);
})
.catch(e => console.log(e));
}
const deleteTodo = (todoNo, index) => {
fetch("/todo", {
method: 'delete',
headers: {"Content-Type" : "application/json"},
body: todoNo
})
.then(res => res.text())
.then(result => {
if(result === '0'){
alert('삭제 실패');
return;
}
const newTodoList = [...todoList];
//배열.splice(인덱스, 숫자)
//-> 배열의 인덱스 몇 번째 태그 부터 몇 칸을 잘라내서 반환할 지 지정
//배열에서 잘라진 부분이 사라짐
newTodoList.splice(index,1); //내가 선택한 번호, 하나만 삭제
/*
새로운 목록 리스트 = newTodoList
괄호안에 작성한 부분 제외하고 목록 새로 작성 = splice
(내가 선택한 번호, 하나만 삭제) = (index,1)
*/
setTodoList(newTodoList); //새로 작성한 목록으로 기존 목록 대체
})
.catch(e => console.log(e));
}
return(
<>
<h1>{loginMember.name}의 Todo List</h1>
<div className="todo-container">
<h3>할 일(todo)입력</h3>
<div>
<input type="text" value={inputTodo} onChange={e => setInputTodo(e.target.value)}/>
<button onClick={addTodo}>할 일 추가하기</button>
</div>
<ul>
{/* 배열.map : 기존 배열 사용해서 새로운 배열 만들기 */}
{todoList.map((todo, index) => (
<li key={keyIndex++}>
<div>
<span className={todo.isDone === 'N' ? 'todo-complete' : ''}>
{todo.title}
</span>
<span>
<button onClick={() => {updateTodo(todo, index)}}>
{todo.isDone === 'Y' ? 'O' : 'X'}
</button>
<button onClick={() => deleteTodo(todo.todoNo, index)}>
삭제
</button>
</span>
</div>
</li>
))}
</ul>
</div>
</>
)
}
export default TodoList;
TodoListContext.js
import React, { createContext } from 'react';
/* 전역 변수 역할의 객체 생성 */
const TodoListContext = createContext();
export default TodoListContext;
App.js
import React, { useState } from 'react';
import './App.css';
import TodoListContext from './components/TodoListContext';
import SignUp from './components/SignUp';
import Login from './components/Login';
import TodoList from './components/TodoList';
/* App 컴포넌트 (최상위 컴포넌트) */
function App() {
/* 상태 변수(값이 변하면 컴포넌트 리랜더링) */
// 회원 가입창 보이기/숨기기
const [signupView, setSignupView] = useState(false);
// 로그인한 회원 정보 저장
const [loginMember, setLoginMember] = useState(null);
// 로그인한 회원의 할 일 목록 저장
const [todoList, setTodoList] = useState([]);
return (
<TodoListContext.Provider value={ {loginMember, setLoginMember, todoList, setTodoList} } >
<button onClick={ () => { setSignupView(!signupView) } } >
{ signupView ? ('회원 가입 닫기') : ('회원 가입 열기')}
</button>
{/* 회원 가입 화면 */}
<div className='signup-wrapper'>
{/* signupView가 true인 경우에만 화면에 출력 */}
{ signupView === true && (<SignUp/>) }
</div>
<h1>Todo List</h1>
{/* 로그인 컴포넌트 */}
<Login />
<hr/>
{/* 로그인 되었을 때 로그인한 회원의 TodoList 출력 */}
{ loginMember && (<TodoList/>) }
</TodoListContext.Provider>
);
}
export default App;
'Springboot-React' 카테고리의 다른 글
tosspay구현하기 3 (springboot) (0) | 2024.07.24 |
---|---|
tosspay구현하기 2 (springboot) (0) | 2024.07.24 |
tosspay 구현하기 1 (react) (0) | 2024.07.24 |
TodoList 만들기 2 (0) | 2024.07.18 |
TodoList 만들기 1 (0) | 2024.07.17 |