【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
が保持しているキャッシュを更新するためのものです。
ディスカッション
コメント一覧
まだ、コメントがありません