[WIL] 5주차 회고

Mark·2022년 9월 4일
1
post-thumbnail
post-custom-banner

5주차는 리액트 심화주차였으며, 프론트엔드 팀원들과 함께 mock api를 설하고 json-server로 투두리스트 게시글 crud, 댓글crud, 로그인, 회원가입을 구현하였다.


공부한 내용

1. Axios

axios란 node.js와 브라우저를 위한 Promise 기반 http 클라이언트라고 소개하고 있다. 즉 http를 이용해서 서버와 통신하기 위해 사용하는 패키지이다.

1) axios 설치

yarn add axios

2) json-server 설정

  • 테스트용 db.json 설정
    {
      "todos": [
        {
          "id": "1",
          "title": "react",
    			"content" : "content"
        }
      ]
    }

3) [GET] 데이터 조회

  • get은 서버의 데이터를 조회할 때 사용하는 메서드이다.
    axios.get(url[, config])
  • get 요청시 path variable or query?
    • json-server 공식문서에서는 전체 전보, 상세 정보는 path variable로 url을 작성하면 되고 filter와 같은 기능을 위해서 get을 요청할 경우에는 query로 보내라고 명시하고 있다.

4) [POST] 데이터 등록

  • post는 서버에 데이터를 추가할 때 사용하는 메서드이다.
  • post 요청에 대한 로직은 백엔드 개발자가 구현하기 때문에 추가 외에 다른 용도로 사용하게 될 수도 있지만 보톤 클라이언트 데이터를 body 형태로 서버에 보내고자 할 때 사용한다.
    axios.post(url[, data[, config]])   // POST
    axios.post("http://localhost:3001/todos", todo);

5) [DELETE] 데이터 삭제

  • delete는 저장되어 있는 데이터를 삭제하고자 요청을 보낼 때 사용한다.
    axios.delete(url[, config])  // DELETE
     axios.delete(`http://localhost:3001/todos/${todoId}`);

6) [PATCH] 데이터 수정

  • patch는 어떤 데이터를 수정하고자 서버에 요청할 때 사용하는 메서드이다.
  • 수정을 할 때 반드시 patch, put을 사용해야 하는 것은 아니다.
  • post를 통해서도 ‘수정'기능을 만들 수도 있긴 하다.
    axios.patch(url[, data[, config]])  // PATCH
    axios.patch(`http://localhost:3001/todos/${todoId}`, edit);

7) 정리

  • Axios를 이용해서 API 서버와 통신할 수 있다.
  • Axios는 http 통신을 도와주는 패키지이며, 구체적인 명세는 API 명세서를 확인해야 한다.
  • 브라우저 네트워크 탭을 잘 봐야한다.
  • http method, status code와 같은 정보들은 백엔드 개발자가 구현해주는 부분이며 백엔드와 프론트엔드의 커뮤니케이션이 잘 되어야한다.
  • 네트워크 통신 이후 화면을 업데이터 해야한다면 프론트엔드에서 추가로 구현해야 한다.

2. 리액트 스터디

  • 리액트 redux-toolkit
  • 리액트 json-server
  • 리액트 mock api
  • 리액트 redux-thunk
  • 리액트 Hooks - useMemo, useCallback, custom hook
  • .env 파일 적용

3. [FE 팀 프로젝트] ToDoList

1) 구현한 기능

  • 리덕스 툴킷, 리덕스 청크 적용
  • [ToDo] 상세 게시글 조회
  • [ToDo] 댓글 등록
  • [ToDo] 댓글 조회
  • [ToDo] 댓글 삭제
  • [ToDo] 댓글 수정

2) 해당 기능을 구현하는데 있어서 꼭 알고있어야 하는 개념

  • redux-toolkit
  • redux-thunk
  • axios
  • json-server
  • useEffect
  • custom hook(알고있으면 좋음)

4. 배운점, 어려웠던 점 & 문제 해결

  • styled-components 파일 분리 후 인자 전달
    • 재사용하는 스타일드 컴포넌트에 props를 전달했는데 받지 못하고 ‘direction’ is not defiend라를 에러가 떴다.

    • 인자를 전달받는 코드에서 ${direction} 으로 받고 있었는데, 이렇게 되면 값을 인지하지 못하는 상황이 발생하여 화살표 함수를 사용해서 아래와 같이 보내주니까 해결이 되었다.

      flex-direction: ${(props) => props.direction};
  • position으로 중앙 정렬시, 위&아래로 화면을 올리거나 내릴경우 구성 요소들도 같이 움직이는 현상
    • 중앙 정렬을 위해 positn을 absolute로 설정하고 left와 top을 %로 주게되면 화면을 작게할 때 박스도 같이 움직이는 문제 발생 → 따라서 %아닌 px로 변경시키니까 화면이 고정되면서 문제가 해결되었다.
  • 프라미스를 반환한다는 의미
    • 실행은 되었지만 결과를 아직 반환하지 않은 객체를 의미한다.
    • 반환되지 않은 상태에서 then을 붙이면 결과가 반환되고
    • 실행이 완료되지 않았으면 완료가 된 후 then 내부에 함수가 실행된다.
    • https://koras02.tistory.com/102
  • 댓글 데이터 삭제시 특정 Id를 삭제하는데 모든 댓글 데이터들이 삭제되는 문제
    • todos, comments, users 3가지로 필드가 나눠져있었는데, 로그인을 하고 users 데이터들이 채워지는 과정에서 userID key와 comments의 useID key이름이 서로 달라서 발생한 문제로 파악되었다.
    • users에서 userID와 comments의 userID로 변경해주고 통일시키니 문제가 해결되었다.
  • update시, editComment를 인식하지 못하는 문제 발생
    • id와 updateComment(객체형태)를 한 번에 updateComments 함수로 dispatch시키는 과정에서 updateComments에서 editComment를 받아오지 못하고 있었다.
    • 문재 해결 방법
      • dispatch시킬 때 {id, updateComment}를 중괄호에 담에서 한 번에 보낸다.

      • __updateComments함수 실행시, id와 updateComment가 담긴 객체를 getEditData라는 변수로 설정해주었다.

        즉 getEditData = {id, updateComment} 형태이다.
        async (getEditData, thunkAPI) => {
      • 구조분해 할당을 이용해서 id, updateComment를 getEditData에서 꺼내준다.

        const { id, updateComment } = getEditData;
      • 그 다음 데이터를 put 시켜주니 문제가 해결되었다.

        const response = await axios.put(
                `http://localhost:5001/comments/${id}`,
                updateComment
              );
  • useEffect에서 데이터 변경사항 있을 시 재렌더링 시키기
    • useEffect의 2번째 인자에 dispatch를 설정해주면 데이터가 업데이트가 되었을 때 화면을 렌더링 시켜준다.
    • 단, redux-tookit을 설정한 모듈에서 extraReducers에 get, add, delete, update 함수들이 실행되었을 경우, useEffect를 통해 화면 렌더링이 가능하다. 처음에 __addComments함수를 실행시켰을 때 state.comments에 아무런 변화가 없어서 데이터를 add시켜도 dispatch가 반응을 안해서 [inputs]을 넣었었는데, 이건 잘못된 방법이고, state.comment에 concat함수를 사용하여 추가한 데이터를 합쳐주는 방식으로 extraReducers에 함수를 변경하니까 댓글을 등록시켰을 때 잘 반영(리렌더링) 되는 것을 확인할 수 있었다.
  • input에 데이터 입력시 값 변화가 Input창에 반영되지 않는 문제 발생
  • json-server로 todo id가 1인 것을 다 삭제 하고 싶을 경우
    • [DELETE] todos/1을 하면 todos id가 1인 것뿐만 아니라 comments에서도 todoId가 1인 것을 다 삭제시켜준다.

      http://localhost:5001/todos/1
  • 얕은 복사, 깊은 복사
    • 리렌더링이 발생하려면 이전 상태와 비교가 필요하다(=메모리 주소)
    • 얕은 복사를 하면 같은 메모리 주소를 가리키고, 내가 값을 바꾸면 이전 값도 변경된다.
      • 업데이트를 감지할 수 없다.
      • 이전과 이후 데이터를 구별할 수 없기 때문에
    • 깊은 복사를 하면 이전 메모리 주소는 변하지 않고, 복사를 한 새로운 데이터가 생성이 되는 것
      • 즉, 이전과 이후 데이터가 다름을 비교할 수 있다.
      • 이전 데이터가 바뀐 값으로 변경되지 않는다.
      • 메모리 주소가 다르다.
      • 업데이트를 감지할 수 있다.
      • 컴포넌트는 최신 상태를 유지해야하고, 리덕스가 불변성을 유지해야 하는 이유이다.
      • 즉 메모리 주소가 서로 다른 곳을 바라보고 있어야 상태 변화를 감지할 수 있음
  • immer도 깊은 복사를 해서 반환하는 원리이다.
  • 원시타입 데이터는 값이 같으면 같은 주소를 가리키게 된다.
    • useMemo는 원시타입을 사용할 필요가 없는가?
    • useMemo(값을 반환)와 useCallBack(함수를 반환)은 상태가 바뀌었을 때 바뀜을 감지하고 실행해서 리턴을 해주는데, 원시형 타입은 값이 바뀌었음을 인지할 수가 없다. (원시형 타입을 디펜던시 어레이로 주었을 경우)
  • redux에서 error나 loading상태를 알려주고 싶을 경우
    • 리덕스 내에 반환해주는 error도 이미 라이브러리에 정의되어 있다.
    • 에러 문구가 뜰 것이다.
    • 인위적으로 error상태를 반드는 방법은 api를 호출하지 않으면 어려울 수 있다.
  • 값이 바뀌었다는 것은 메모리 주소가 바뀌었다는 것인가?
    • 데이터가 바뀌는거랑 메모리 주소가 바뀌는 것은 다르다.
    • 데이터 타입별 메모리 할당이 어떻게 이루어지는지는 공부해보는 것이 좋다.

5. 멘토님과 Q&A

Q. todos 데이터를 useState로만 관리해도 되는지, redux를 사용해도 괜찮은지?

  • A. 모든 API에 pending, fulfilled, rejected를 thunk로 구현하지 않아도 된다. useSelector에서 값을 가져와서 안전하게 useState로 관리해도 된다(?)
  • db에 저장된 값을 사용해서 여러 컴포넌트에서 사용하고 사용하게 될 경우 리덕스 store에 저장하면 된다. useState는 휘발성이라서 리셋이되면 초기화가 되기 때문이다.

Q. 로그인 기능 구현시 토큰 값을 store에 저장해도 되는지?

  • A. localStorage를 사용하거나 쿠키, 세션에 저장해서 사용할 수 있다. store에 저장하는 것은 보안 문제가 발생할 수 있기 때문에 지양하는 것이 좋다.

5주차 리액트 숙련을 마치며

이번주차는 오랜만에 팀프로젝트를 하는 주차였다. 먼저 프론트엔드 팀원들과 팀프로젝트를 하는 주차였고, 다음 주차에 백엔드와 협업하기 전에 json-server를 활용하여 가상의 db를 설계하고 api를 설계해서 데이터를 주고 받는 연습을 진행하였다. 내가 담당한 주 기능은 댓글 CRUD였고, 하고 싶었던 기능이라 기대가 되었다.

처음엔 특정 todo에 해당하는 댓글을 가져와야 하는 부분, 특정 todo에 해당하는 댓글을 삭제하고 등록하고 수정해야 되는 것에서 db를 어떻게 구성하고 데이터를 주고 받아야 하는지 감이 잘 안잡혔었는데, 팀원들에게 정리가 안되는 부분들과 이해가 안되는 것들을 여쭤보면서 문제를 해결해나갔다. 또한 axios로 서버와 어떻게 통신을 하게 되는지에 대해서, 비동기처리, 화면 조건부 랜더링 useEffect를 활용해서 데이터의 state가 변경되었을 경우에만 렌더링 시키는 방법등에 대해서 배울 수 있었던 양질의 시간이었다.

그리고 댓글 comment를 구현하는 과정에서 순탄하지 않게 나도 너무 어려움을 느끼면서 해결했기 때문에 같은 고민을 하고 계신 분이 있으시다면 도움을 드리고 싶은 마음에 살짝 오지랖을 부려서 같은 기능을 구현하시는 분들에게 약간의 설명을 해드렸다. 아무래도 양질의 설명은 아니었지만 조금이나마 도움이 될 수 있었으면 싶은 마음이었는데, 도움이 되셨다는 말씀을 듣고 더 열심히 공부하고 싶은 마음과 동기부여가 되었다.

서로 알려주고 문제를 해결하는 과정은 서로에게 많은 도움을 주는 것 같다. 같이 성장하는 기분이 든다!! 이 마음을 잊지 않고 겸손한 마음으로 배우려는 자세, 언제나 모를 수 있고 다 옳은 게 아니라는 생각으로 더 열심히 공부하자!


참고 자료

profile
개인 공부 정리
post-custom-banner

0개의 댓글