페이지 매김 추가
33305 단어 tailwindcssreactmarkdownnextjs
ExamPro 마크다운 랩 파트 2
이것은 ExamPro Next.js 과정의 일부입니다. 페이지 매김 및 작업 유형 필터링과 같은 추가 콘텐츠가 이 실습에 추가됩니다.
이 실습에서는 기존 애플리케이션에 페이지 매김 기능을 추가합니다.
페이지네이션 기능 추가
http://localhost:3000/jobs
는 다음과 같습니다.
구성 파일
이 파일은 한 페이지에 표시할 작업 수를 설정하는 데 사용됩니다.
./config/index.js
export const JOBS_PER_PAGE = 4;
페이지네이션 컴포넌트
./components/jobs/Pagination.js
import Link from 'next/link';
import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/solid';
import { JOBS_PER_PAGE } from '@/config/index';
export default function Pagination({ currentPage, numJobs, numPages }) {
const isFirst = currentPage === 1;
const isLast = currentPage === numPages;
const prevPage = `/jobs/page/${currentPage - 1}`;
const nextPage = `/jobs/page/${currentPage + 1}`;
const firstJobOfPage = parseInt((currentPage - 1) * JOBS_PER_PAGE + 1);
const lastJobOfPage = parseInt(currentPage * JOBS_PER_PAGE);
if (numPages === 1) return <></>;
return (
<div className="bg-white px-4 py-3 flex items-center justify-between border-t border-gray-200 sm:px-6">
<div className="flex-1 flex justify-between sm:hidden">
{/* If not first page, display the Previous link */}
{!isFirst && (
<Link href={prevPage}>
<a className="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50">
Previous
</a>
</Link>
)}
{/* If not last page, display the Next link */}
{!isLast && (
<Link href={nextPage}>
<a className="ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50">
Next
</a>
</Link>
)}
</div>
<div className="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between">
<div>
<p className="text-sm text-gray-700">
Showing <span className="font-medium">{firstJobOfPage}</span> to{' '}
<span className="font-medium">{lastJobOfPage > numJobs ? numJobs : lastJobOfPage}</span>{' '}
of <span className="font-medium">{numJobs}</span> results
</p>
</div>
<div>
<nav
className="relative z-0 inline-flex rounded-md shadow-sm -space-x-px"
aria-label="Pagination"
>
{/* If not first page, display the Previous link */}
{!isFirst && (
<Link href={prevPage}>
<a className="relative inline-flex items-center px-2 py-2 rounded-l-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50">
<span className="sr-only">Previous</span>
<ChevronLeftIcon className="h-5 w-5" aria-hidden="true" />
</a>
</Link>
)}
{/* Loop through numPages array */}
{Array.from({ length: numPages }, (_, i) => (
<li key={i} className="list-none">
<Link href={`/jobs/page/${i + 1}`} passHref>
{i == currentPage - 1 ? (
<a
aria-current="page"
className="z-10 bg-orange-50 border-orange-400 text-orange-500 relative inline-flex items-center px-4 py-2 border text-sm font-medium"
>
{i + 1}
</a>
) : (
<a className="bg-white border-gray-300 text-gray-500 hover:bg-gray-50 relative inline-flex items-center px-4 py-2 border text-sm font-medium">
{i + 1}
</a>
)}
</Link>
</li>
))}
{/* If not last page, display the Next link */}
{!isLast && (
<Link href={nextPage}>
<a className="relative inline-flex items-center px-2 py-2 rounded-r-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50">
<span className="sr-only">Next</span>
<ChevronRightIcon className="h-5 w-5" aria-hidden="true" />
</a>
</Link>
)}
</nav>
</div>
</div>
</div>
);
}
페이지 매김을 추가하려면 작업 목록에 대한 새로운 동적 경로가 필요합니다.
pages/jobs/page/[page_index].js
파일import { promises as fs } from 'fs';
import path from 'path';
import matter from 'gray-matter';
import { JOBS_PER_PAGE } from '@/config/index';
import Job from '@/components/jobs/Job';
import Layout from '@/components/Layout';
import Pagination from '@/components/jobs/Pagination';
export async function getStaticPaths() {
// Read from the /jobs directory
const files = await fs.readdir(path.join('jobs'));
// Get the number of files and divide by JOBS_PER_PAGE then round up
const numPages = Math.ceil(files.length / JOBS_PER_PAGE);
let paths = [];
for (let i = 1; i <= numPages; i++) {
paths.push({
params: { page_index: i.toString() },
})
}
return {
paths,
fallback: false,
}
}
export async function getStaticProps({ params }) {
const page = parseInt((params && params.page_index) || 1);
// Read from /jobs directory
const files = await fs.readdir(path.join('jobs'));
// Map through jobs directory
const jobs = files.map(async (filename) => {
// Set 'slug' to name of md file
const slug = filename.replace('.md', '');
// Read all markdown from file
const markdown = await fs.readFile(path.join('jobs', filename), 'utf-8');
// Extract data from markdown
const { data } = matter(markdown);
// return slug and data in an array
return {
slug,
data,
};
});
// Get total number of jobs
const numJobs = files.length;
// Get the number of files and divide by JOBS_PER_PAGE then round up
const numPages = Math.ceil(files.length / JOBS_PER_PAGE);
// Get the page index
const pageIndex = page - 1;
// Display only the number of jobs based on JOBS_PER_PAGE
const displayJobs = jobs.slice(pageIndex * JOBS_PER_PAGE, (pageIndex + 1) * JOBS_PER_PAGE);
return {
props: {
jobs: await Promise.all(displayJobs),
numJobs,
numPages,
currentPage: page,
},
};
}
export default function JobPostings({ jobs, numJobs, numPages, currentPage }) {
return (
<Layout title="Jobs | ExamPro">
<div className="px-4 py-4 sm:px-6 md:flex md:items-center md:justify-between">
<div className="flex-1 min-w-0">
<h2 className="text-2xl font-bold leading-7 text-gray-900 sm:text-3xl sm:truncate">
Job Postings
</h2>
</div>
</div>
<div className="bg-white my-4 shadow overflow-hidden divide-y divide-gray-200 sm:rounded-md">
<ul role="list" className="divide-y divide-gray-200">
{/* Maps through each job */}
{jobs.map((job, index) => (
<Job key={index} job={job} />
))}
</ul>
</div>
<Pagination currentPage={currentPage} numJobs={numJobs} numPages={numPages} />
</Layout>
);
}
pages/jobs/index.js
및 pages/jobs/page/[page_index.js]
에서 대부분 동일한 기능을 사용하므로 다음과 같이 pages/jobs/index.js
가져오기에서 모든 항목을 삭제할 수 있습니다.import { getStaticProps } from './page/[page_index]';
import JobPostings from './page/[page_index]';
export { getStaticProps };
export default JobPostings;
Reference
이 문제에 관하여(페이지 매김 추가), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/cindyledev/create-a-job-listing-using-nextjs-tailwindcss-and-markdown-2oh3텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)