【Next.js】Next.js + useSWR + Material-uiでPagiNationを実現
はじめに
こんにちは、がんがんです。
前回のNext.js関連の記事にて、データをキャッシュすることが出来るSWRについて備忘録を書きました。
gangannikki.hatenadiary.jp
今回は、前回記事の最後で触れているuseSWR + PagiNationに関する備忘録を書いておきます。
今まであったuseSWRPagesは廃止されたようなので、今後の自分のためにも備忘録をまとめておきます。
公式ドキュメント
新しいライブラリに関しては参考記事がないので公式ドキュメントを参考にしていきます。
swr.vercel.app
参考記事(仕様変更で現在は使えないもの)
SWRライブラリの更新により、現在のバージョンではuseSWRPagesが廃止されました。
そのため、下記の記事は使えませんが参考としてまとめておきます。
Please update to the latest version (≥ 0.3.0) to use this API. The previous useSWRPages API is now deprecated.
「zeit/swr」のpagination exampleでScroll Position Restoreを試す - Qiita
インストール
前回の記事でインストールなどは済ませているので割愛します。こちらを参照ください。
gangannikki.hatenadiary.jp
環境
- Next.js
- Material-ui
- swr
フロント部分
まずはフロント部分を用意します。
/pages/TestPage.js |
import React, { useState } from 'react'; import Container from '@material-ui/core/Container'; import Grid from '@material-ui/core/Grid'; import { makeStyles } from '@material-ui/core/styles'; import Pagination from '@material-ui/lab/Pagination'; import CardArea from '../components/CardArea'; const useStyles = makeStyles((theme) => ({ cardGrid: { paddingTop: theme.spacing(8), paddingBottom: theme.spacing(8), }, pageNation: { paddingBottom: theme.spacing(8), }, })); const Search = () => { const classes = useStyles(); const [pageIndex, setPageIndex] = useState(1); const handlePageChange = (e, v) => { setPageIndex(v); } return ( <div> <Container className={classes.cardGrid} maxWidth="md"> <Grid container spacing={4}> <CardArea index={pageIndex} /> </Grid> </Container> <Container className={classes.pageNation} maxWidth="lg"> <Pagination page={pageIndex} count={maxCard} color="primary" size="large" onChange={handlePageChange} renderItem={(item) => ( <PaginationItem page={item.page} component={Link} naked href={`/search${item.page === 1 ? '' : `?page=${item.page}`}`} {...item} /> )} /> </Container> </div> ); } export default Search;
Data fetch部分(今回のメイン)
/components/Cards.js |
import React from 'react'; import useSWR from 'swr'; import Card from '@material-ui/core/Card'; import CardContent from '@material-ui/core/CardContent'; import CardMedia from '@material-ui/core/CardMedia' import Grid from '@material-ui/core/Grid'; import Typography from '@material-ui/core/Typography'; import { makeStyles } from '@material-ui/core/styles'; import Skeleton from '@material-ui/lab/Skeleton'; const useStyles = makeStyles((theme) => ({ card: { height: '100%', display: 'flex', flexDirection: 'column', }, cardMedia: { paddingTop: '56.25%', // 16:9 }, cardContent: { flexGrow: 1, }, })); const fetcher = (...args) => fetch(...args).then(res => res.json()) const Cards = ({ index }) => { const classes = useStyles(); const { data, error } = useSWR(`api/test?${index}`, fetcher); const cards = data ? [].concat(data.test) : []; return ( <> {cards.map((card, index) => { return ( <Grid item xs={12} sm={6} md={4} key={index}> <Card className={classes.card}> <CardMedia className={classes.cardMedia} image={card.image} title="Design Image" /> <CardContent className={classes.cardContent}> <Typography variant="h4" component="h2" align="center" gutterBottom> {card.title} </Typography> <Typography variant="h6" align="center" gutterBottom> <Skeleton animation="false" /> </Typography> </CardContent> </Card> </Grid> ); })} </> ); } export default Cards;
おわりに
今回はswrを使ったPagiNationについて実験を行いました。
useSWRPagesの代用として登場したuseSWRInfiniteについても触ってみたので後々備忘録書きたいと思います。