이번엔 실질적으로 권한이 있는 유저만 해당 내용을 볼 수 있게끔 해볼 것이다.
이블로그를 참고해서 만들었다.
먼저 클라이언트에 todo가 보일 수 있게 todo를 저장하는 state를 만들자.
const [todoList, setTodoList] = useState([]);
이제 todo를 서버에서 읽어와야한다.
todo에 userId를 저장한다고 가정하고 restAPI를 구현해보자
const readList = async () => {
if (!token) {
console.log("No token available, cannot read list");
return;
}
try {
const { data } = await axios.get(`http://localhost:4444/todos?userId=${userId}`, {
headers: { Authorization: `Bearer ${token}` }
});
setTodoList(data);
console.log("Todo list loaded:", data);
} catch (error) {
console.error("할 일 목록 읽기 실패:", error.response?.data || error.message);
}
};
그러면 언제 todo를 읽어와야 할까?
1.todo가 삭제될 때
2.todo가 생성될 때
3.로그인 할 때
1,2번은 post도 구현해야하니 3번부터 구현하자.
로그인하면 token이 저장되니 token값이 바뀌면 readList 함수를 불러오게끔 해보자
useEffect(() => {
if (token) {
readList();
}
}, [token]);
우선 화면에 보일 수 있도록 jsx를 작성한다.
const [description, setDescription] = useState("");
{/* Todo Form */}
{token && (
<>
<h2>추가하기</h2>
<input
placeholder="할 일"
type="text"
value={description}
onChange={(e) => setDescription(e.target.value)}
/>
<button onClick={handleSubmit}>추가하기</button>
<br />
</>
)}
이제 버튼을 눌렀을 때 실제로 할 일이 추가되도록 하자.
todo를 만들기 위해선 1.todo의 내용 2.수행여부 3.userId가 필요하다.
이 내용들을 body에 넣어 restAPI를 보내보자.
const handleSubmit = async () => {
try {
const { data } = await axios.post(
"http://localhost:4444/todos",
{
description,
isCompleted: false,
userId
},
{
headers: { Authorization: `Bearer ${token}` }
}
);
alert(data.description + "이 추가되었습니다.");
setDescription("");
await readList();
} catch (error) {
console.error("할 일 추가 실패:", error.response?.data || error.message);
}
};
이제 직접 값을 넣어보자!
값이 야무지게 들어온다.
그렇다면 이제 할 일 목록이 보이게끔 해보자!
{/* Todo List */}
{token && (
<div>
<h2>할 일 목록</h2>
<ul>
{todoList?.map((todo) => (
<div key={todo.id}>
<li>{todo.description}</li>
<button
onClick={() => toggleCompleteBtn(todo.id, todo.isCompleted)}
>
{todo.isCompleted ? "완료" : "미완료"}
</button>
<button onClick={() => deleteTodoBtn(todo.id)}>삭제하기</button>
</div>
))}
</ul>
</div>
)}
이제 수행여부와 삭제버튼을 만들어보자.
수행여부는 그냥 boolean값을 반대로 해주면 된다.
const toggleCompleteBtn = async (id, isCompleted) => {
try {
await axios.patch(
`http://localhost:4444/todos/${id}`,
{
isCompleted: !isCompleted,
},
{
headers: { Authorization: `Bearer ${token}` }
}
);
await readList();
} catch (error) {
console.error("할 일 상태 변경 실패:", error.response?.data || error.message);
}
};
삭제는 delete메소드를 사용했다.
const deleteTodoBtn = async (id) => {
try {
await axios.delete(`http://localhost:4444/todos/${id}`, {
headers: { Authorization: `Bearer ${token}` }
});
await readList();
} catch (error) {
console.error("할 일 삭제 실패:", error.response?.data || error.message);
}
};
완성!
참고
https://minhanpark.github.io/%EC%8B%9C%EB%A6%AC%EC%A6%88/json-server-auth/