2주 프로젝트 다이어리 - 비동기 순서 파악하기(axios 요청과 react-router 의 순서)

🐶·2021년 9월 6일
3

프로젝트

목록 보기
8/10
post-thumbnail

React로 개발을 할 때 routing 방식을 React-router로 구현하게 된다. React는 SPA의 방식이기 때문에 React-router 역시 route 주소로 변경되면서 동적으로 바뀌는 부분만 Rerendering이 되게 되는데, 이러한 방식은 a tag를 이용해 페이지를 이동할 때보다 빠르다는 장점이 있다. (체감상 0.0001초도 아니고 누르자마자 이동된 느낌을 받는다.) 그런데, 상황에 따라 이러한 점이 UX적으로 단점으로 작용할 때가 있는데, 이번 상황이 그러한 상황이었다.

새 피드 작성, 내 피드 수정, 내 피드 삭제할 때, 홈으로 다시 돌아갔을 때 바로 변경사항이 적용되지 않는 버그가 있었다.

문제점

  1. writing 페이지에서 유저가 제목, 이미지파일 업로드, 내용 등 모두 채우고 '등록'버튼을 눌렀을 때 서버로 axios POST 요청을 보낸다.(새 피드를 post테이블의 레코드로 추가하는 요청)
const Writing = () => {
const createFeedHandle = () => {
    // 피드테이블에 레코드 생성하는 axios POST 요청(지영)
    // 해당 피드 페이지 or 홈화면으로 Redirect 필요
      axios.post(
        "http://ec2-3-34-191-91.ap-northeast-2.compute.amazonaws.com/posting",
        {
          title: title,
          choice_1: firstOpt,
          choice_2: secondOpt,
          img_1: firstImg, 
          img_2: secondImg, 
          contents: content,
          hashTags: JSON.stringify(isClicked), 
        },
        {
          headers: {
            authorization: accessToken,
          },
          "Content-Type": "application/json",
        }
      );
    }
};
  1. '등록'버튼엔 아래와 같이 <Link>태그로 이동하게 되어 있다.
const Writing = () => {
  
  //...
  
  return (
    //...
    
   <Link to="/">
      <button className={styles.submitBtn} onClick={createFeedHandle}>
        등록
      </button>
    </Link>
)}
  1. '등록'버튼을 누르자마자 보이는 홈 화면에서는 새롭게 추가된 피드가 보이지 않는다.

버그 원인

홈화면으로의 이동을 react-router로 구현하게 되었을 때

  1. 홈화면으로의 페이지 이동 -->
  2. 그 다음 홈화면에서 전체 피드를 불러오는 GET axios 요청 --->
  3. 새 피드가 post테이블에 레코드로 추가되는 axios post 요청

이 순서대로 일어났기 때문에, DB에 레코드가 추가 되기도 전에 전에 홈화면이 먼저 보여졌던 게 문제였다.

해결 방법

전역에 listRender라는 state 하나를 생성하였다(초기값은 true). 이 상태값을 전역 useEffect 함수(전체 피드를 불러오는 GET axios요청 담당)의 의존성 배열값으로 두었다. 그리고 글쓰기/글수정/글삭제 버튼이 눌릴 때마다 listRender의 값이 전환되어 useEffect hook 내의 함수가 호출되도록 하였다.(false-> true, true-> false)

const Writing = () => {
const createFeedHandle = () => {
    // 피드테이블에 레코드 생성하는 axios POST 요청(지영)
    // 해당 피드 페이지 or 홈화면으로 Redirect 필요
      axios.post(
        "http://ec2-3-34-191-91.ap-northeast-2.compute.amazonaws.com/posting",
        {
          title: title,
          choice_1: firstOpt,
          choice_2: secondOpt,
          img_1: firstImg, 
          img_2: secondImg, 
          contents: content,
          hashTags: JSON.stringify(isClicked), 
        },
        {
          headers: {
            authorization: accessToken,
          },
          "Content-Type": "application/json",
        }
      );
  	setListRender(); //listRender라는 state의 값을 전환시키는 함수 호출.
    }
};

전역에서의 useEffect함수는 아래와 같다.

useEffect(() => {
      axios
      .get(
        "http://ec2-3-34-191-91.ap-northeast-2.compute.amazonaws.com/get-all-post"
      )
      .then((res) => {
        if(sortValue === '최신순'){
          let result = res.data.data.sort((a, b) => {
            return new Date(b.created_at) - new Date(a.created_at);
          });
          setFeeds(
            result.map((el) => {
              return {...el, tags: JSON.parse(el.tags),
            }}))
        } else if(sortValue==='인기순'){
          let result = res.data.data.sort((a, b) => {
            return (b.option1_count+b.option2_count) - (a.option1_count+a.option2_count);
          });
          setFeeds(
            result.map((el) => {
              return {...el, tags: JSON.parse(el.tags),
            }}))
        }
      });

  }, [listRender]); //listRender값이 변하면 useEffect hook 내의 함수 호출됨. 

이렇게 해주었는데도... 문제가 해결되지 않았다.

근본적인 데이터 흐름 순서를 다시 짚어보고 변경 후 순서가 되려면 기존2번 과정에서 setTimeout으로 의도된 타임 딜레이를 둬야할 것 같았다.

<기존 순서>
1. 홈화면으로의 페이지 이동 -->
2. 그 다음 홈화면에서 전체 피드를 불러오는 GET axios 요청 -->
3. 새 피드가 post테이블에 레코드로 추가되는 axios post 요청

<변경 후 순서>
1. 홈화면으로의 페이지 이동 -->
2. 새 피드가 post테이블에 레코드로 추가되는 axios post 요청 -->
3. 그 다음 홈화면에서 전체 피드를 불러오는 GET axios 요청

따라서 아래와 같이 useEffect 내 함수를 수정해주었다.

useEffect(() => {
    setTimeout(() => {
      axios
      .get(
        "http://ec2-3-34-191-91.ap-northeast-2.compute.amazonaws.com/get-all-post"
      )
      .then((res) => {
        if(sortValue === '최신순'){
          let result = res.data.data.sort((a, b) => {
            return new Date(b.created_at) - new Date(a.created_at);
          });
          setFeeds(
            result.map((el) => {
              return {...el, tags: JSON.parse(el.tags),
            }}))
        } else if(sortValue==='인기순'){
          let result = res.data.data.sort((a, b) => {
            return (b.option1_count+b.option2_count) - (a.option1_count+a.option2_count);
          });
          setFeeds(
            result.map((el) => {
              return {...el, tags: JSON.parse(el.tags),
            }}))
        }
      });
    }, 300);
  }, [listRender]); //글쓰기 버튼이 눌려질 때 마다 axiosGET요청 보내기.

그랬더니..... 해결!!!

참고자료: https://chooworld.com/2021/03/11/react%EC%97%90%EC%84%9C-%EB%AA%87-%EC%B4%88-%ED%9B%84-redirect-%EA%B8%B0%EB%8A%A5-%EB%A7%8C%EB%93%A4%EA%B8%B0/

profile
우당탕탕 개발일기📝🤖

0개의 댓글