overflow: hidden;과 함께 사용
white-space: nowrap; 속성
과거 브라우저에서 지원하던 것이라서 현재는 사용하지 않는걸 권장한다.
PostContentBox: styled.div`
margin: 10px;
font-size: 17px;
letter-spacing: 1px;
line-height: 25px;
padding: 15px;
max-height: 25%;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2; /* 표시할 줄 수 설정 */
-webkit-box-orient: vertical; /* 텍스트의 방향 설정 */
`,
GlobalStyle에 ::selection
에 스타일을 넣어주면 된다!
body {
margin:0;
padding:0;
font-family: 'Pretendard-Regular';
::selection {
background-color: ${(props) => props.theme.mainPurpleColor};
color: ${(props) => props.theme.whiteColor}
}
}
(!)타입 단언을 하면 변수가 항상 정의된 값이라고 알려줄 수 있다.
api
const fetchComments = async (id: string, page: number): Promise<any> => {
const itemsPerPage = 4; // 한 페이지당 보여줄 댓글 개수
// 해당 페이지의 시작 인덱스 계산
const startIndex = (page - 1) * itemsPerPage;
// 댓글 데이터 가져오기
const { data } = await supabase
.from('comment')
.select()
.eq('postid', id)
.range(startIndex, startIndex + itemsPerPage - 1);
// 총 댓글 개수 가져오기
const { count } = await supabase.from('comment').select('count', { count: 'exact' }).eq('postid', id);
// 총 페이지 개수 계산
const totalPages = Math.ceil(count! / itemsPerPage);
// 데이터와 총 페이지 개수를 객체로 묶어서 반환
return { data, totalPages };
};
무한 스크롤과 유사하게 데이터의 범위를 설정하고 총 페이지 개수가 필요하니 총 페이지 개수를 계산하여 데이터와 함께 return해주었다.
Comments
const { id } = useParams<{ id: string }>();
const [page, setPage] = useState<number>(1);
const {
isLoading,
isError,
data: comments
} = useQuery<any>(
['comment', id, page], // queryKey 수정
() => fetchComments(id!, page), // queryFn 수정
{ keepPreviousData: true }
);
console.log('comments', comments);
const onClickPage = (selected: number | string) => {
// 같은 페이지를 그대로 클릭시 함수종료
if (page === selected) return;
if (typeof selected === 'number') {
setPage(selected);
return;
}
if (selected === 'prev' && page > 1) {
setPage((prev) => prev - 1);
return;
}
if (selected === 'next' && page < comments.total_pages) {
setPage((prev) => prev + 1);
return;
}
};
.
.
(
<ul>
{comments?.data?.map((comment: any) => (
<li key={comment.commentid}>{comment.text}</li>
))}
</ul>
)}
<Pagination currentPage={page} totalPages={comments?.totalPages ?? 1} onClick={onClickPage} />
return값이 데이터와 총 페이지 개수이니 데이터를 map으로 뿌려주고 총 페이지 개수가 필요한 부분에 적용하여 페이지네이션을 구현하였다.
import Pagination from 'react-js-pagination'
라이브러리를 사용하여 페이지네이션을 스타일링 할 수 있다.
{comments?.data?.map((comment: any) => (
<>
<S.Comment key={comment.commentid}>
<div>
<S.CommentName>{comment.name}</S.CommentName>
<S.CommentDate>{new Date(comment.date).toLocaleString()}</S.CommentDate>
</div>
{user?.userid === comment.userid && (
<S.ButtonBox>
<S.button onClick={() => handleCommentEdit(comment)}>
{comment.commentid === editingCommentId ? '저장' : '수정'}
</S.button>
<S.button onClick={() => handleCommentDelete(comment.commentid)}>삭제</S.button>
</S.ButtonBox>
)}
{comment.commentid === editingCommentId ? (
<S.EditInput
type="text"
value={editedCommentText}
onChange={(e) => setEditedCommentText(e.target.value)}
/>
) : (
comment.text
)}
</S.Comment>
</>
))}
<P.PageLists>
<Pagination
activePage={page}
itemsCountPerPage={4}
totalItemsCount={comments?.totalPages * 4 ?? 0}
pageRangeDisplayed={5}
prevPageText={`◀`}
nextPageText={`▶`}
onChange={setPage}
/>
</P.PageLists>
activePage={현재 페이지}
itemsCountPerPage={한 페이지 당 데이터 개수}
totalItemsCount={총 데이터 개수}
pageRangeDisplayed={ Paginator 내에서 보여줄 페이지의 범위}
prevPageText={◀
}
nextPageText={▶
}
onChange={현재 페이지의 setState}
prefetchQuery를 사용하여 페이지네이션을 구현하시는 것을 보았다. react query는 파면 팔수록 새로운 기능들이 나오고 동작과정을 이해하는게 중요하다는 것을 다시 되세기는 시간이 되었다.
내일은 알고리즘이랑 못했던 공부들을 하자!