데이터 로딩 화면 추가
어떻게 짜도 디자인이 너무 구려서 결국 png 파일 이용하기로 함..^^
스크롤 맨 위로 올리기
버튼을 누르면 스크롤이 맨 위로 부드럽게 올라간다
리액트 페이지네이션 직접 구현하기
[React.js] API를 연동한 Pagination 구현
인터넷 계속 찾아보다가 그냥 내가 머리 굴려서 구현함~
다음에는 그냥 라이브러리 써봐야지 ㅎ
여행 리스트 데이터가 들어오면
1. 데이터 개수로 총 페이지 수를 구한다.
반올림(데이터개수/한페이지에 나타낼 목록 개수)
2. 1 ~ 총페이지수까지 2차원 배열에 담아준다.
페이지를 5개씩 보여주고싶다면 [[1,2,3,4,5],[6,7,8,9,10]] 이런식으로
3. 페이지 인덱스 초기값 0 -> pagelist[인덱스]의 값을 보여준다.
3-1. >(다음)을 누르면 index++(index가 마지막이 아닌지)
3-2. <(이전)을 누르면 index--(index가 0이 아닌지)
3-3. <<(처음)을 누르면 index = 0;(index가 0이 아닌지)
3-4. >>(끝)을 누르면 index = last;(index가 마지막이 아닌지)
4. curpage 선택된 페이지 초기값 1
페이지 하나에 보여줄 개수를 지정하여 해당 개수만 보여줌
만약에 페이지당 4개의 게시글이라면
1 page -> 0~3
2 page -> 4~7
...
이런식으로 전체 데이터에서 필터 조건을 걸어 해당 인덱스의 데이터만 받아온다.
얼렁뚱땅 짠 코드라 부끄럽지만 누군가에게 도움이될 수도 있으니..
function Contents() {
const navigation = useNavigate();
const { mytrip } = React.useContext(StoreContextTrip);
const cnt = 5;
const [viewlist, setViewlist] = React.useState([]);
const [curpage, setCurpage] = React.useState(1);
const [pagelist, setPagelist] = React.useState({
index: 0,
list: [],
});
React.useEffect(() => {
if (mytrip.trip.length > 0) {
//총 페이지 계산
const totalpage = Math.ceil(mytrip.trip.length / cnt);
const array = PageListMakeHandler(totalpage);
//현재 페이지가 총 페이지보다 뒤에 있으면 마지막 페이지로 set
if (totalpage < curpage) {
setCurpage(totalpage);
}
//인덱스가 삭제되고 -1 해주기
if (pagelist.list.length > 0 && !pagelist.list[pagelist.index]) {
setPagelist((prevState) => {
return {
...prevState,
index: pagelist.list.length - 1,
};
});
}
// 페이지 리스트 저장
setPagelist((prevState) => {
return {
...prevState,
list: array,
};
});
}
}, [mytrip.trip]);
let PageListMakeHandler = (totalpage) => {
let array = [];
let tmp = [];
//페이지 리스트 만들기
for (let i = 1; i <= totalpage; i++) {
tmp.push(i);
if (i % 5 === 0) {
array.push(tmp);
tmp = [];
} else if (i === totalpage && tmp.length < 5) {
array.push(tmp);
tmp = [];
}
}
return array;
};
React.useEffect(() => {
//현재 페이지에 따라 보여줄 데이터 필터
if (mytrip.trip.length > 0) {
const start = curpage * cnt - cnt;
const end = curpage * cnt - 1;
const array = mytrip.trip.filter(
(data, index) => index >= start && index <= end
);
setViewlist(array);
}
}, [curpage, mytrip.trip]);
const FirstPageHandler = () => {
//처음 페이지가 아닌 경우
if (pagelist.index > 0) {
setPagelist((prevState) => {
return {
...prevState,
index: 0,
};
});
}
};
const LastPageHandler = () => {
//마지막 페이지가 아닌 경우
if (pagelist.index !== pagelist.list.length - 1) {
setPagelist((prevState) => {
return {
...prevState,
index: pagelist.list.length - 1,
};
});
}
};
const PrevPageHandler = () => {
//처음 페이지가 아닌 경우
if (pagelist.index > 0) {
setPagelist((prevState) => {
return {
...prevState,
index: pagelist.index - 1,
};
});
}
};
const NextPageHandler = () => {
//마지막 페이지가 아닌 경우
if (pagelist.index !== pagelist.list.length - 1) {
setPagelist((prevState) => {
return {
...prevState,
index: pagelist.index + 1,
};
});
}
};
return (
<div className="content-mytrip">
{mytrip.trip.length === 0 ? (
<span>아직 작성된 여행이 없습니다! 여행 계획을 세워보세요!</span>
) : (
<>
<div className="mytriptitlebar">
<span className="number">번호</span>
<span className="triptitle">타이틀</span>
<span className="host">방장</span>
<span className="matecnt">참여수</span>
<span className="time1">생성 날짜</span>
<span className="time2">수정 날짜</span>
</div>
<div className="triplistbox">
<ul>
{viewlist.map((data, index) => (
<li key={index} className="item mytrip">
<span className="number">
{index + cnt * (curpage - 1) + 1}
</span>
<span
className="triptitle"
onClick={() => {
navigation(`/mytrip/plan/${data.seq}`);
}}
>
{data.title}
</span>
<span className="host">{data.host_nickname}</span>
{Object.keys(JSON.parse(data.mate_idx)).length === 1 ? (
<span className="matecnt">1명</span>
) : (
<span className="matecnt">
{Object.keys(JSON.parse(data.mate_idx)).length}명
</span>
)}
<span className="time1">
{moment.tz(data.reg_time, "Asia/Seoul").format("YY-MM-DD")}
</span>
{!data.update_time ? (
<span className="time2"></span>
) : (
<span className="time2">
{moment
.tz(data.update_time, "Asia/Seoul")
.format("YY-MM-DD")}
</span>
)}
</li>
))}
</ul>
</div>
<div className="pagelistbox">
<span className="tofirst" onClick={FirstPageHandler}>
{"<<"}
</span>
<span className="toprev" onClick={PrevPageHandler}>
{"<"}
</span>
<ul className="pagelist">
{pagelist.list.length > 0 && (
<>
{pagelist.list[pagelist.index] ? (
<>
{pagelist.list[pagelist.index].map((data, index) => (
<li
key={index}
className={data === curpage ? "item select" : "item"}
onClick={() => setCurpage(data)}
>
{data}
</li>
))}
</>
) : (
<>
{pagelist.list[pagelist.index - 1].map((data, index) => (
<li
key={index}
className={data === curpage ? "item select" : "item"}
onClick={() => setCurpage(data)}
>
{data}
</li>
))}
</>
)}
</>
)}
</ul>
<span className="tonext" onClick={NextPageHandler}>
{">"}
</span>
<span className="tolast" onClick={LastPageHandler}>
{">>"}
</span>
</div>
</>
)}
</div>
);
}
테스트 하다보니까 오류 지점 발견 - 추가는 문제가 없는데 삭제에서..
1. 현재 보고있는 페이지에서 글이 다 삭제되면 오류 -> curpage-1 해줌
2. 페이지 목록의 첫번째에 데이터가 다 삭제되면 오류(index값에 해당하는 데이터가 없어서 데이터를 받기전에 html이 렌더링 되면서 오류가 남) -> html에 true일때 false일때해서 false이면index-1값 넣어줌 어차피 데이터 받아오면 셋 다시 하니까
수정도 잘 되고요
없는 게시글이거나 내가 속한 게시글이 아니면 열람 불가
로그인 세션을 확인한 후 없으면 login 페이지로 이동한다.
와 이제 메인,이용방법 페이지만 만들면 배포..!!