오늘의 이슈 리렌더링

lim1313·2021년 11월 15일
0

😎 오늘의 할 일

  1. like, unlike 테스트, 수정
  2. delete /posts
  3. put /posts/edit ?? => 하경님과 상의
  4. postCards 변경사항 전달
  5. loading 페이지
  6. empty page
  7. loginId 전달 필요

🤔 오늘의 이슈

1. 로그인 로그아웃시 페이지 리렌더링 문제

로그인 로그아웃 페이지 리렌더링 버그 수정

로그인한 후 /beans 페이지에 접속하고, 로그아웃한 후 다른 아이디로 로그인했을 때 /beans 페이지가 리렌더링되지 않는 문제가 있었다.

문제 상황
app.js에서 useEffect를 통해 랜더링될 때마다 isLogin 상태를 확인하고 setLogin하도록 되어있었다.
그렇기 때문에 isLogin을 props로 받는 하위에 있는 컴포넌트들도 isLogin 상태가 변화될 때마다 리랜더링될 것이라고 예상하였다.

예를 들면,
test1으로 로그인하고 beans페이지로 간 후, beans페이지에서 로그아웃을 하고 test2로 로그인을 하였을 때, test2가 좋아하는 원두목록이 나오도록 beans페이지가 리랜더링되는 것이다.

결과,
하지만, 예상과는 달리, beans페이지는 리랜더링되지 않고, 새로고침을하거나 다른페이지를 들어갔다가 되돌아와야 상태가 변화되었다.

나의 착각...
isLogin이 상태변화되면 props로 받는 하위컴포넌트가 리렌더링되는 것은 맞다. 하지만, 하위 컴포넌트의 state를 변경해 주지 않았기 때문에, 보여지는 beans페이지가 그대로였던 것이다.

그래서, 해결은
각 컴포넌트에 isLogin를 props로 전달하여 상태 변화에 따라 useEffect가 실행되도록 하고, loginId에 해당하는 값을 요청하여 state값을 변경해주니 제대로 동작하는 것을 확인할 수 있었다.

굉장히 간단한 문제였고, react의 기본적인 개념이었는데, 많은 state, props로 구현하다보니 기본적인 부분을 놓치게 되었던 것 같다.

export default function Beans({ loginId }) {
  const [allBeanName, setAllBeanName] = useState([]);

  const [beans, isLoading, setBeans] = useLoading([], getAllBeans, loginId);
  const [openModal, cardBeanInfo, cardPostInfo, beanModal, closeModal] = useBeanModal(beans);
  
  ...}
export function useLoading(inital, httpService, arg) {
  const [data, setData] = useState(inital);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    setIsLoading(true);
    httpService()
      .then((res) => {
        setData(res);
        setIsLoading(false);
      })
      .catch((err) => {
        console.log(err.response);
      });
  }, [arg]);

  return [data, isLoading, setData];
}

2. beans 페이지 4번이나 네트워크통신..?

3. 회원가입 화면 구현시 빈번한 통신

회원가입 과정에서 아이디를 중복검사하는 단계가 있다. 최종적으로는 버튼을 눌러서 중복판별 요청을 보내도록 구현하였지만, 글자를 입력할 때마다 실시간으로 중복판별할 수 있는 로직도 괜찮다고 생각하였다.

하지만 한 글자를 쓸 때마다 중복판별을 위해 서버요청을 보내는 것은 비효율적인 것 같다.

네이버의 경우를 보니 onBlur가 되었을 때 한번 서버 요청을 보내는 것을 확인하였고, 이처럼 한번, 혹은 적은 수의 서버요청으로 중복판별하는 방법도 있었다.

이 프로젝트에서 로그인 부분은 내 파트가 아니기때문에 원하는 방향으로 진행하지는 못했지만, 다음 프로젝트 때에는 다음과 같은 방법으로 구현하면 좋을 것 같다.

  1. setTimeout으로 판별하는 방법이 있을 것이다. 즉 input 창이 onFocus되고 user가 onkeydown을 멈추고 1초 후에 한번 요청을 보내는 것이다. 이렇게하면 적은 수의 요청으로 중복판별을 할 수 잇다.

  2. 네이버처럼 onblur되었을 때 하는 것이다. 하지만 user가 이를 모르고 계속 중복판별을 기다리며 onblur하지 않을 수 있는 문제점이 있기는 한 것 같다.

3. rest api 분기 불필요

//TODO 모든 원두 가져오기
export const getAllBeans = async () => {
  const res = await axios.get(`${http}/bean/all-beans`);
  return res.data.beanList;
};

//TODO 필터링 원두 가져오기
export const getFilterBeans = async (data) => {
  const res = await axios.get(`${http}/bean/filter-beans`, { params: { ...data } });
  return res.data;
};

백엔드 분과 대화를 하다가 나온 주제이기도 하다.
모든 원두를 가져오는 것과 필터링한 원두를 가져오는 rest api의 엔드포인트를 굳이 분기할 필요가 없었고, 분기를 하니 더 번거로운 작업이었다고 하였다.

즉, GET 원두는 /bean로 하고, params를 통해 filter인지 아닌지를 판별할 수 있기 때문에 굳이 엔드포인트를 나눌 필요는 없었다.

4. rest api 추가(전달 완료)

게시물 삭제

  1. Delete /posts
    request => body : {data : {postId}}
    response => 성공시 204 / 실패시 400

게시물 댓글 작성

  1. POST /posts/comment
    request => body : { data: { postId, comment } }
    response => { userId: 'userId',commentId: 1, comment: 'new 내용댓글 내용',createAt: '2020-12-20 시분초'}

게시물 댓글 삭제

  1. DELETE /posts/comment
    request => body : { data: { postId, commentId } }
    response => 성공시 204 / 실패시 400

게시물 댓글 수정

  1. PUT /posts/comment
    request => body : { data: { postId, commentId, editComment }}
    response => 성공시 204 / 실패시 400

특정 게시물 내용, 댓글 가져오기

  1. GET /posts?post-id=postId
    request
    response
{
  postCotents: {
    title: 'this is titlethis is titlethis is title',
    imageUrl: '/asset/beans/bean4.jpg',
    beanRatio: {
      자바: 4,
      케냐: 2,
      '탄자니아 킬리만자로 AA': 4,
      '탄자니아 킬리만자로 A': 4,
      '탄자니아 킬리만자로': 4,
    },
    water: 15,
    waterTemp: 80,
    content:
      '게시물 내용 이것은 게시물 내용 이것은 게시물 내용 이것은\n 게시물 내',
    userId: 'meme',
    createAt: '2020-12-20 시분초',
  },
  comments: [
    {
      userId: '작성자id입니다',
      commentId: 1,
      comment: '댓글 내용댓글 내용댓글 내용댓글 내용',
      createAt: '2020-12-20',
    },
    {
      userId: 'userId',
      commentId: 2,
      comment: '댓글 내용댓글 내용댓글 내용댓글 내용',
      createAt: '2020-12-20',
    },
    {
      userId: '작성자임',
      commentId: 3,
      comment: '댓글 내용댓글 내용댓글 내용댓글 내용댓글 내용댓글 내용댓글 내용댓글 내용댓글 내용',
      createAt: '2020-12-20',
    },
    {
      userId: '작성자id입니다',
      commentId: 4,
      comment: '댓글 내용',
      createAt: '2020-12-20',
    },
  ],
};

http => https 로 변경

http 배포로 진행하려 했으나 구글 크롬의 2월 업데이트 내용(쿠키 전송 이슈) 때문에 https 배포로 전환하게 됐고, 그것때문에 여러 CORS 에러가 발생

cookie options cors error 정리

sameSite : none => 항상 쿠키를 보내줄 수 있다. 다만 쿠키 옵션 중 Secure 옵션이 필요하다
secure : https 프로토콜을 이용하여 통신하는 경우에만 쿠키를 전송

app.use(
  cors({
    origin: [
      'https://localhost:3000', 'http://localhost:3000',
      'https://www.beanus.tk', 'http://www.beanus.tk',
      'https://practic.beanus.tk', 'http://practic.beanus.tk'
    ],
    credentials: true,
    methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  })
);
 sendAccessToken: (res, accessToken) => {
    res.cookie('accessToken', accessToken, {
      httpOnly: true,
      secure: true,
      sameSite: 'None',
      expires: new Date(Date.now() + 1000 * 60 * 60 * 48),
    });
  },

😎 DevLog

기본의 중요성

오늘은 어떻게 프로젝트에 기여했나요?

  • /posts/view/:id 라우트 정리 완료
  • like/unlike 서버 통신 테스트 완료
  • 로그인 로그아웃 후의 페이지 렌더링 에러 해결
  • /posts/view/:id의 댓글 작성, 수정, 삭제 기능 구현
  • loading page 추가

오늘 프로젝트에서 힘들었던 점은 무엇인가요?

  • 로그인 로그아웃시 페이지 리렌더링 문제가 있었다. test1으로 로그인하고 beans페이지로 간 후, beans페이지에서 로그아웃을 하고 test2로 로그인을 하였을 때,test2가 좋아하는 목록이 체크된 beans페이지가 랜더링되어야 하는데, test1의 목록이 그대로 남아있는 문제였다.

오늘 프로젝트에서 아쉬웠던 점은 무엇인가요?

  • react 렌더링에 대한 이해가 부족하여 로그인 로그아웃 시 발생하는 페이지 리렌더링 에러 해결에 어려움을 겪기도 했다. 기본적인 개념이었지만, 많은 state, props로 구현하다보니 기본적인 부분을 놓치게 되었던 것 같다.

내일은 프로젝트에 기여하기 위해 무엇을 해야 하나요?

  • 게시글 삭제 서버 통신 테스트
  • 댓글 작성, 수정, 삭제 서버 통신 테스트
  • 페이지 라우팅시 한번이 아닌 여러번 GET 요청이 되는 에러 문제 해결
  • navbar css 에러 보조
  • empty page 추가
  • loading페이지 적용 논의 필요
profile
start coding

0개의 댓글

관련 채용 정보