React로 개발을 할 때 routing 방식을 React-router로 구현하게 된다. React는 SPA의 방식이기 때문에 React-router 역시 route 주소로 변경되면서 동적으로 바뀌는 부분만 Rerendering이 되게 되는데, 이러한 방식은 a tag를 이용해 페이지를 이동할 때보다 빠르다는 장점이 있다. (체감상 0.0001초도 아니고 누르자마자 이동된 느낌을 받는다.) 그런데, 상황에 따라 이러한 점이 UX적으로 단점으로 작용할 때가 있는데, 이번 상황이 그러한 상황이었다.
새 피드 작성, 내 피드 수정, 내 피드 삭제할 때, 홈으로 다시 돌아갔을 때 바로 변경사항이 적용되지 않는 버그가 있었다.
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",
}
);
}
};
<Link>
태그로 이동하게 되어 있다.const Writing = () => {
//...
return (
//...
<Link to="/">
<button className={styles.submitBtn} onClick={createFeedHandle}>
등록
</button>
</Link>
)}
홈화면으로의 이동을 react-router로 구현하게 되었을 때
이 순서대로 일어났기 때문에, 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요청 보내기.
그랬더니..... 해결!!!