【React】Next.jsを使ってみた
Next.jsで遊んでみた内容をメモしています。
getStaticProps
ビルド時に処理を行い、事前に静的なファイルを生成します。
ローカル起動時はアクセス毎に処理を行います。
export const getStaticProps: GetStaticProps = async () => {
const response = await fetch('https://example.com/data')
const data = await response.json()
return {
props: {
data
}
}
}getStaticPropsの結果がpropsに格納されます。dataというプロパティに格納したので、props.dataでアクセスできます。
interface Props {
data: InferGetStaticPropsType<typeof getStaticProps>
}
const App: React.FC<Props> = (props) => {
// getStaticPropsの結果が表示されます
console.log(props.data)
return (
<div></div>
)
}getStaticPaths+getStaticProps
公式によると、/post/[id].js のようにする事で、[id]に動的なパラメータを設定したURLを生成できます。[id]の部分を取得するのが、getStaticPathsになります。
export const getStaticPaths: GetStaticPaths = async () => {
const response = await fetch(`https://example.com/data`)
const data = await response.json()
const paths = data.map((x:any) => {
return {
params: {
id: String(data.id),
},
}
})
return {
paths: paths,
fallback: false,
}
}getStaticPathsで取得した[id]を元に、事前に静的なファイルを生成します。
export const getStaticProps: GetStaticProps = async ({ params }) => {
const id = params.id
const response = await fetch(`https://example.com/data/${id}`)
const data = await response.json()
return {
props: {
data
}
}
}getStaticPropsの結果がpropsに格納されます。dataというプロパティに格納したので、props.dataでアクセスできます。
const Posts: React.FC = (props: any) => {
return (
<div>
{props.data.map((data) => <Post key={data.id} data={data} />)}
</div>
)
}URLが/post/[id].js なので、postsというフォルダの中に [id].js を作成します。
import Link from "next/link";
interface Props {
post: any;
}
const Post: React.FC<Props> = ({ data }) => {
return (
<div>
<Link href={`/posts/${data.id}`}>
<span>{data.text}</span>
</Link>
</div>
);
}
export default Post;fallback
getStaticPathsにfallback: falseを指定しましたが、false以外にもtrueとblockingがあります。
- false:ビルド時に静的ページが作成されなかった場合、その後に静的ページが追加されても404になります。
- true:ビルド時に静的ページが作成されなかった場合、その後に静的ページが追加されるとアクセスできます。
- blocking:
fallback: trueとほぼ同じ動きですが、blockingはgetStaticPaths()が完了してから表示されます。
以下は公式ドキュメントのソースの一部です。fallback: trueの場合、getStaticPaths()の非同期処理中はisFallbackがtrueになります。fallback: blockingの場合、isFallbackが使用できません。
function Post({ post }) {
const router = useRouter()
if (router.isFallback) {
return <div>Loading...</div>
}
// Render post...
}
export async function getStaticPaths() {
const res = await fetch(`https://.../posts/${params.id}`)
const post = await res.json()
return {
paths: [{ params: { id: '1' } }, { params: { id: '2' } }],
fallback: true,
}
}getStaticProps+Incremental Static Regeneration
getStaticPropsでビルド時に静的ファイルした後は更新されないのですが、revalidateを指定する事で再生成されるようになります。
この辺の動きはややこしくて、
1. データを更新する
2. Aさんがアクセスした際は古い内容が表示される
3. Aさんが参照した時点でファイル再生成処理が動く
4. Bさんがアクセスした際は新しいデータ(1.で更新したデータ)が表示される
という動きになるみたいです。revalidate: 10とすると、最大で10秒に1回に再生成処理が動作します。
export const getStaticProps: GetStaticProps = async () => {
const response = await fetch('https://example.com/data')
const data = await response.json()
return {
props: {
data,
},
revalidate: 10,
}
}useSWR
リアルタイムに画面を表示したい場合、SWRというhooksが便利です。
公式のソースコードを参考にすると、こんな感じになります。
const fetcher = (url: any) => fetch('https://example.com/data').then(response) => response.json());
const Posts: React.FC<Props> = ({ posts }) => {
const { data } = useSWR('/api/posts', fetcher, { initialData: posts })
}
export const getStaticProps: GetStaticProps = async () => {
const response = await fetch('https://example.com/data')
const data = await response.json()
return {
props: {
posts,
},
revalidate: 10,
}
}useSWRの戻り値にmutateというのがあり、ここがうまくまとまっていて分かりやすかったです。mutateはSWRが保持しているキャッシュを更新するためのものです。


ディスカッション
コメント一覧
まだ、コメントがありません