마지막으로 게시글 수정 기능을 내가 도맡아 했었다.
마실꾼 프로젝트에서 게시글 수정 기능을 구현하면서 가장 먼저 고민했던 부분은 “내가 쓴 글에만 수정 버튼이 보이고, 다른 사람은 접근할 수 없도록 막는 것”이었다.
처음에 크게 세 단계로 나누어 생각했다.
표시 단계: 상세 페이지에서 내 글일 때만 수정 버튼이 보이도록 했다.
접근 단계: URL로 직접 /post/:id/edit에 들어올 경우에도 본인 글이 아니면 막았다.
PostEditPage.jsx 에서 게시글을 불러올 때 현재 로그인한 사용자 정보와 게시글 작성자 ID를 함께 가져오도록 했다. 두 값을 비교해서 작성자가 아니면 곧바로 상세 페이지로 돌려보냈다.
useEffect(() => {
const loadPostData = async () => {
const [userResponse, postResponse] = await Promise.all([
baseApi.get("/user/me"),
baseApi.get(`/articles/${id}`),
]);
const userData = userResponse.data?.data || userResponse.data;
const postData = postResponse.data?.data || postResponse.data;
const isAuthor =
userData &&
postData &&
(String(userData.id) === String(postData.authorId) ||
String(userData.id) === String(postData.author?.id) ||
String(userData.id) === String(postData.userId));
if (!isAuthor) {
alert("본인이 작성한 게시글만 수정할 수 있습니다.");
navigate(`/app/post/${id}`);
return;
}
// 게시글 데이터 세팅...
};
if (id) loadPostData();
}, [id, navigate]);
이때 String() 비교를 추가해서 서버 응답이 숫자일 수도, 문자열일 수도 있는 상황에 안전하게 대응하도록 했다.
이후,
상세 페이지(PostCoursePage)에서는 내 글일 때만 수정 버튼이 보이도록 조건부 렌더링을 했다.
const canEdit =
!!me &&
!!post &&
(String(me.id) === String(post.authorId) ||
String(me.id) === String(post.author?.id) ||
String(me.id) === String(post.userId));
return (
<div className="post-course-page">
{canEdit && (
<button
className="edit-button"
onClick={() => nav(`/app/post/${post.id}/edit`)}
>
수정하기
</button>
)}
</div>
);
이렇게 하니 다른 사람이 쓴 글에는 수정 버튼이 아예 보이지 않게 만들 수 있었다.
마지막으로 저장할 때 서버에서 401(로그인 필요)이나 403(권한 없음)을 내려주는 경우를 처리했다. catch 블록에서 상태 코드에 따라 알림을 띄우고 로그인 페이지나 상세 페이지로 돌려보냈다.
} catch (err) {
const status = err?.response?.status;
if (status === 401) {
alert("로그인이 필요합니다.");
navigate("/login");
return;
}
if (status === 403) {
alert("내 게시글이 아니어서 수정할 수 없습니다.");
navigate(`/app/post/${id}`);
return;
}
alert("게시글 수정에 실패했습니다. 다시 시도해주세요.");
}
이렇게 열심히 구현을 했는데, 게시글 수정의 사진이 뜨지 않은 오류가 발생했다.

알고보니, 프론트에서는 수정된 사진을 photoUrl에 넣고 있었고, 백엔드에서는 새로운 사진을 newImages 에 넣고, 기존의 사진을 photoUrl 에 넣어 사진이 수정되면 null값으로 넣는 로직으로 구현되어있었다. 이후 필드명을 수정했더니 정상적으로 잘 작동을 하였다.


프로젝트를 통해 프로젝트 경험의 중요성을 크게 느꼈다. 프론트엔드 팀원으로 참여하며 협업 과정 속에서 개발자의 역할과 프로젝트의 전체적인 흐름을 스스로 정리할 수 있는 기회가 되었다. 단순히 기능 하나를 구현했다는 성취감보다, 프로젝트를 전반적으로 경험하며 이해하게 되었다는 점이 굿이였다.
1. UI 디테일을 직접 구현할 수 있었다
Figma 시안을 기반으로 게시글 카드, 사이드바, 검색창, 지도 레이아웃 등을 세세하게 맞추는 경험을 했다. 작은 마진과 간격, 아이콘 위치, 반응형 레이아웃까지 직접 개발자도구 Application을 보면서 다듬으면서 디자인 구현을 배울 수 있었다.
2. API와의 연동을 통해 프론트와 백엔드 협업을 경험했다
게시글 생성/수정/삭제, 로그인/회원가입, 토큰 관리 등 실제 API를 붙여서 기능을 만들었다.
3. 배포를 처음 배우게 되었다
Vite 빌드 시 index.html 엔트리 누락, SPA 딥링크 404 문제 등 로컬에서는 괜찮아도 배포 후 발생하는 문제들을 해결했다. 프론트엔드 개발자는 로컬만 보는 게 아니라 배포 환경까지 고려해야 한다는 점을 배웠다.
마실꾼 프로젝트 하면서 개인적으로 수정되었으면 하는 부분을 적어보았다.
1. 좋아요 & 스크랩북 기능이 게시글 상세코스와 메인화면 부분에 서로 반영이 정상적으로 되지 않은 점이 아쉬웠다.
2. 게시글 수정하기에서는 위치인증을 다시 하지 않으면 '유효하지 않은 상세지역입니다'라고 떴다. Mapview.jsx에서 위치 정보까지 가져왔었어야 했는데, 따로 구현해버려서 연결하지 못한 부분이 아쉬웠다.
3. 프로필 이미지 바꾸고 나서 무조건 새로고침을 해야 프로필 사진이 변경되는데.. 변경하기 버튼을 누르면 자동으로 바뀌도록 구현해보면 좋을 것 같다.
API 연결, React 사용이 아직 익숙치 않아서 그런 부분에 집중하는 바람애 다른 협업적 부분과 기술적 부분에 신경을 쓰지 못했던 것 같다. 다음 프로젝트에서는 GitHub 코드리뷰 문화 정착, 기능별 브랜치 전략, Jotai를 활용한 상태 관리, TailwindCSS 과 Emotion CSS와 같은 다양한 기술적 도전을 해보고 싶다. 또, 개인적으로 학습을 하였던 React 최적화 기법(useMemo, useCallback, React.memo)을 실제 프로젝트에 적용하여 성능 개선과 유지보수성을 높이는 경험도 해보고 싶다.
안녕하세요 수진님, 프로젝트 트랙 4기 수료 축하드립니다🥹
기술적으로 많은 성장을 이뤄내신 거 같아서 좋네요! 프론트엔드에 아직 적용시킬 수 있는 기술이 많다는 사실이 볼 때마다 놀라운거 같아요. 이번 기회로 점점 분야를 넓혀가며 실력 기르시며 더 멋진 개발자로 성장하시기를 기원하겠습니다!! 앞으로도 화이팅입니다‼️