아직 프론트 + 풀스텍의 걸음마를 때는 주니어 개발자이지만
postgresql,react,nodejs 로 데이터를 넣었다 뺄수 있는 todo list 생성에 대한
자료가 많이 없는 것같아서 깃허브 주소를 공개한다.
깔끔한 코드는 아니기 때문에 디비 구동 및 버튼 클릭시 기능변경만 참고해주기를 바란다,
하단은 서버(백), 클라이언트(프론트)이다
https://github.com/fangmin26/server
https://github.com/fangmin26/client
프론트 구현전에 백에서 5000번 포트 기준으로 postgresql 연결 후 기존 데이터 베이스와 테이블을 만들고
데이터베이스 테이블의 id값과 id값의 내용물을 라우팅하는 쿼리문을 작성하여 구동여부를 포스트맨 data.json으로
확인해준다.
정상적으로 작동하면 프론트 각 컴퍼넌트에 해당 5000번 포트를 패칭해주어 기능을 실행해준다.
//ListTodo.js
import React, { useEffect, useState } from "react";
import EditTodo from "./EditTodo";
const ListTodo = () => {
const [todos, setTodos] = useState([]);
// const [modal, setModal] = useState(false);
//delete todofunction
const deleteOnClick = async (id) => {
try {
// const deleteTodo = await fetch(`http://localhost:5000/todos/${id}`, {
// method: "DELETE",
// });
// console.log(deleteTodo);
setTodos(todos.filter((todo) => todo.todo_id !== id));
} catch (error) {
console.error(error.message);
}
};
const getTodos = async () => {
try {
const response = await fetch("http://localhost:5000/todos");
const jsonData = await response.json();
console.log(jsonData);
/*edit 실행시 배열 순서 변경되는 부분 todo_id기준으로 배열 sort 해서 해결*/
function idSort(a, b) {
if (b.todo_id == a.todo_id) {
return 0;
}
return b.todo_id > a.todo_id ? 1 : -1;
}
jsonData.sort(idSort);
console.log(jsonData);
setTodos(jsonData);
} catch (error) {
console.error(error.message);
}
};
useEffect(() => {
getTodos();
}, []);
console.log(todos);
return (
<div style={{ width: "100%" }}>
<h1>list todos</h1>
<table>
<tbody>
{todos.map((todo) => (
<tr key={todo.todo_id}>
<td
style={{
padding: "20px",
width: "25%",
borderBottom: "1px solid red",
}}
>
{todo.description}
</td>
<td
style={{
padding: "20px",
width: "25%",
borderBottom: "1px solid red",
}}
>
<EditTodo todo={todo} />
</td>
<td
style={{
padding: "20px",
width: "25%",
borderBottom: "1px solid red",
}}
>
<button onClick={() => deleteOnClick(todo.todo_id)}>
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
};
export default ListTodo;
//InputTodo.js
import React, { useState } from "react";
const InputTodo = () => {
const [description, setDescription] = useState("");
const onSubmitForm = async (e) => {
e.preventDefault();
try {
const body = { description };
const response = await fetch("http://localhost:5000/todos", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
console.log(response);
//window.location.href="주소":이전페이지 기록을 남김,뒤로가기가능
// window.location.replace("주소")=뒤로가기불가능
window.location = "/";
} catch (error) {
console.error(error.message);
}
};
return (
<div id="inputtodo">
<h1>perntodolist</h1>
<form onSubmit={onSubmitForm} style={{ disaplay: "flex" }}>
<input
type="text"
value={description}
onChange={(e) => setDescription(e.target.value)}
/>
<button>add</button>
</form>
</div>
);
};
export default InputTodo;
//EditTodo.js
import React, { useState } from "react";
const EditTodo = ({ todo }) => {
const [modal, setModal] = useState(false);
/*showModal*/
const showModal = () => {
setModal(!modal);
};
return (
<div>
<button onClick={showModal}>Edit</button>
{modal ? <Modal showModal={showModal} todo={todo} /> : null}
</div>
);
};
const Modal = ({ todo }) => {
const [description, setDescription] = useState(todo.description);
// edit
const updateDescription = async (e) => {
e.preventDefault();
try {
const body = { description };
const response = await fetch(
`http://localhost:5000/todos/${todo.todo_id}`,
{
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
}
);
window.location = "/";
console.log(response);
} catch (error) {
console.error(error.message);
}
};
return (
<div
id="Modal"
key={todo.todo_id}
style={{
background: "rgba(0,0,0,0.1)",
position: "fixed",
top: 0,
left: 0,
width: "100%",
height: "100%",
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
<div
style={{
width: "60%",
height: "60%",
background: "white",
position: "relative",
}}
>
<h1>this is modal</h1>
<input
value={description}
onChange={(e) => setDescription(e.target.value)}
type="text"
style={{ width: "80%", height: "60%", border: "1px solid black" }}
/>
<div
style={{
width: "100%",
display: "flex",
justifyContent: "center",
}}
>
<div
style={{
width: "20%",
paddingTop: 30,
display: "flex",
justifyContent: "space-between",
}}
>
<button onClick={updateDescription}>편집</button>
{/* <button onClick={() => setDescription(todo.description)}>
저장
</button> */}
{/* showModal을 props로 가져올수가 없어 #Modal을 강제로 자바스크립트 구문으로 선택후 삭제해 주었다. */}
<button
onClick={() => {
document.querySelector("#Modal").style.display = "none";
}}
>
닫기
</button>
</div>
</div>
</div>
</div>
);
};
export default EditTodo;