답변을 작성할 경우 title을 뺴고 내용만을 작성하여 데이터를 서버로 전달하고 해당 데이터를 바로 받아와서 작성된 답변이 실시간으로 보이도록 했다. 작업을 하던중 실시간으로 보여주려 했으나 새로고침을 해야 볼 수 있었다. 이것은 windows.location.reload()를 사용하여 새로고침을 하여 해결했다.
질문 작성 기능 구현
답변 수정 페이지 구현
답변 수정하기 페이지의 로직도 질문 수정하기 로직이랑 똑같은 형식으로 진행된다. 그리고 두 개의 컴포넌트를 처음에 하나로 사용했었는데 질문하기에는 title이 존재하고, 답변 수정 페이지에는 title이 존재하지 않아서 삼항연산자를 사용해 하나의 컴포넌트로 사용하려 했지만 아직 실력이 부족했던 것 같다. 다음에는 조금 더 컴포넌트를 재사용할 수 있도록 작성해봐야겠다.
백엔드 서버와 통신을 해보았다. 서버와 통신을 하기전 axios를 사용하여 서버에 요청하느 코드를 작성해 두어야 했기에 JSON 서버를 사용하여 통신을 했었다. 이제 백엔드분들이 서버를 구현하셨다고 하여 우리 코드를 하드코딩하여 통신이 되는지 여부를 확인했고, 회원가입, 질문작성, 질문수정 기능에 대한 통신 테스트를 했다.
테스트를 하던 중 CORS 오류가 있어서 프로트쪽에서 package.json 파일에 Proxy 설정을 해주고 백엔드분들이 CORS 에러를 잡아주어 원활한 테스트를 할 수 있었고 요청에 따른 응답값이 잘 넘언오는 것을 확인했다.
JSON 서버 데이터를 구성할 때 API 명세서와 조금 다르게 작성이 되어 이부분을 고치는 수정 작업이 필요해졌다... 메인 프로젝트때는 처음부터 API 명세서에 맞춰서 JSON 서버 데이터를 구성해 봐야겠다.
질문 상세 페이지에 작성된 title, body의 데이터를 Link 컴포넌트를 사용하여 질문 수정 페이지로 이동하면서 url에 state값으로 질문의 아이디값, 제목, 내용을 넘겨준다.
이동된 페이지에서 useLocation을 사용하여 url에 담아둔 state값을 useState에 할당하고 input에 defaultvalue를 설정해주어 수정전 작성 내용을 보여준다. 이후 수정이 된다면 state값이 변하고, 이 값을 axios를 사용하여 서버측에 headers에 토큰값과 함께 넘겨준다.
먼저 틀을 잡는게 꽤나 고생을 했었다. Navbar와 크기가 비슷하게 어우러져야 했던게 가장 큰 이유였다.
해당 글을 클릭했을 때 주소값에 질문의 ID를 Param에 담아서 전달해 오면 Param에 담긴 ID로 get요청을 하여 ID에 해당하는 질문에 대한 정보를 나타내는 것으로 시작했다. 아직 없는 데이터들은 하드코딩을 하여 일반적인 텍스트를 담아두었다. Vote 버튼, history, 뒤로가기 등이 있다.
오른쪽 사이드바의 경우 메인에서 나와있는 팀원이 만들어둔 메인 사이드바를 가져와서 배치시켰다. 이유는 CSS 부분을 조금적게 하고 기능적인 부분에 조금더 비중을 두기 위해서였다. 프리프로젝트인 만큼 디자인 쪽 보다는 백엔드와의 통신, 기능 부분을 자세히 해보는 것이 중요하다고 생각했기 때문이다.
그리고.... 질문의 내용을 보여주려 할 때, 일반적으로 div태그 안에 내용을 전달해주면 될 것이라는 안일한 생각을 했다. 그 결과 질문 작성 페이지에서 줄바꿈이 일어난 시점을 제대로 화면에 출력해주지 못하는 일이 있었다. 검색을 통해 pre 태그라는 것을 사용한다면 띄어쓰기, 줄바꿈 등의 모든 것을 반영하여 화면에 출력해준다는 사실을 알게되어 적용해서 해결할 수 있었다.🥳 확실히 코딩을 할 때 궁금한 것은 여러가지 사이트를 찾아보면서 해결하는 것이 재미있다!!!😀
질문 링크 공유하기 구현
질문의 링크를 공유하고 싶다는 생각이 들어서 찾아보던중 navigator.clipboard.writeText 라는 것을 발견하게 되었고 사용했더니 해당 질문 페이지의 링크를 클립보드에 저장해주었고 실제로 적용이 되었다. (로컬에서만 적용되고 주소가 http로 바뀌니 보안성 때문에 복사되지 않는 이슈 발생)
navigator.clipboard
.writeText(`http://localhost:3000/questions/${questionId}`)
// 링크 복사에 성공하게 될 경우 alert 창 출력
.then(() => {
window.alert("Link copy complete!");
});
질문 삭제 구현
질문 수정하기를 먼저 구현하려 했지만 수정하기 위해선 하나의 페이지가 더 필요하다는 것을 알게되어서 가장 쉽게 할 수 있는 삭제하기를 먼저 구현했다. 나는 CRUD 중 가장 수운 부분은 삭제하기라고 생각이 든다. 실제 업무에서는 데이터는 곧 회사의 자산이기 때문에 삭제대신 글을 숨기는 식으로 진행이 된다고 알고 있지만 프리 프로젝트인 만큼 삭제 그 자체를 구현하기로 했다.
실제 오버플로우에서는 삭제전에 질문을 복구할 수 있도록 휴지통 같은 개념의 스택에 담아 두는 것으로 알고 있다.
질문 상세 페이지 구현
답변 보기 틀 구현
질문 보기와 같은 구조로 이루어져 있다는 것이 파악되어 질문 보기 컴포넌트를 재사용하여 빠르고 간단하게 구현할 수 있었다. props로 값만 따로 보내주면 된다고 판단했기 때문이다.
답변 작성 틀 구현
답변을 작성하면 해당 페이지가 재랜더 되면서 작성된 답변이 실시간으로 올라오는 것이 되어야 했다. 이것에 꽤나 애를 먹었다. 너무 빠른 속도로 재랜더링이 되면 해당 답변이 올라가기도 전에 재랜덩이 되어 실시간으로 반영이 되지 않았던 것이다.
그래서 아래와 같은 코드로 답변이 정상적으로 올라간다면 then에서 재랜더링이 작동이 되도록하니 바로 해결할 수 있었다. 간단한 이유였는데 너무 파악을 늦게한 것 같다.
axios를 사용할때 비동기적으로 async, await을 사용해야하는데 이것을 사용하지 않는 것도 문제라고 생각했다.....
코스에서 알려준 내용은 하나의 인스턴스에서 EC2, S3를 결합하여 배포하는 형식으로 알려주었다. 하지만 이번에는 백엔드 계정, 프론트엔드 계정을 따로 두어 배포해보기로 하였다. 아이디 공유가 신경쓰였기 때문이지만 IAM를 사용하여 권한을 부여한 계정을 팀원에게 전달하는 방식도 있긴하지만 프리티어가 몇개까지 적용되는지 알 수 없어서 따로 계정을 사용하기로 했다.
그래서 완성은 되지 않았지만 1차적으로 npm run build를 진행하고 배포해보았다. 코스에서 배운대로 webpack.config 파일 같은 설정을 하고 빌드를 해보려 했지만 조금 에러가 많이 생겨서 일반 빌드를 진행했다.
배포 결과는.... 좋은 결과였다. 하지만, 이미지가 제대로 적용되지 않는 상황이 발생했다. 찾아보니 num run build를 진행하면 build 폴더 → index.html 파일의 파일 경로가 /static/.../으로 절대경로 방식으로 되어 있던게 문제라고 한다. 이것을 ./static/.../이런식으로 상대경로로 바꿔주니 문제가 해결되었다.
사실 경로는문제가 없었던듯 하다... 무슨 문제가 원인이었을지 다시 한 번 찾아봐야겠다..!
해당 페이지를 작성할 때 가장 고생했던 부분은 배경에 이미지를 넣는 것이었다. 로봇이랑 체크 박스가 담긴 이미지 인데 svg파일로 되어있고 원하는 위치에 올리는 것이 너무 힘들었지만 div로 감싸서 위치를 맞추고 배경을 넣었더니 해결이 되었다. (동기분의 조언으로 완료!!) 제목과 내용이 비어있을 경우 empty title, body라는 내용이 출력되도록 유효성 검사까지 진행했다.
제목과 내용을 작성하고 post yourt question버튼을 클릭했을 때 axios.post를 사용하여 데이터가 서버쪽에 담기는 지 확인하기위해 JSON 서버를 사용하여 API 명세서에 맞춰 틀을 구현하였다. 아직 백엔드분들이 서버 로직을 구현하는 단계였기 때문에 확인을 하려면 JSON 서버를 사용하는 것이 가장 빠른 방법이라고 생각했기 때문이다.
post메서드가 정상적으로 작동하여 JSON 서버 db에 담기는 것 까지 확인하였다. 추후 서버와 연동시 URL 주소와 CORS 부분을 해결하면 동작 가능하도록 코드를 작성했다.
오른쪽 사이드바 구현
오른쪽 사이드바는 원래 페이지에서는 계속 스텝이 변화하면서 바뀌는 식으로 나오게 되지만 CRUD 기능에 조금더 힘을 쏟기 위해 간단하게 Step1만 틀로 구현하였다. 아코디언 형식으로 보고싶은 곳을 클릭했을 때 내용이 나오고 열려있던 내용은 닫히는 것을 구현했다.
스터디에서 컴포넌트 만들기를 한주에 하나씩 구현해내는 것을 진행했었는데 이때 한번 작성해봐서 이번 프로젝트에서 구현하는데 굉장히 많은 도움이 되었다.