Next.js_2 (ApolloClientとmakeVar編)
typescriptのmicrosoft公式ドキュメント
https://www.typescriptlang.org/docs/handbook/2/basic-types.html
海外でのわかりやすいチートチャート
https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/forms_and_events
■7. 基本Layoutの作成
7-1. componentsディレクトリ直下に、Layout.tsxを作成
cd components touch Layout.tsx(macのターミナル) New-Item Layout.tsx(Windowsのシェルスクリプト)
Layout.tsx はじめの一歩。
ReactNode→childrenをPropsで渡すので、そのデータ型としてReactNodeを設定。
VFC→Reactのファンクショナルコンポーネント(VFC)のデータ型で、childrenのデータ型を明示的に含まない。
import { ReactNode, VFC } from 'react' import Head from 'next/head' import Link from 'next/link' import Image from 'next/image'
interface→「型」を、アプリケーション全体を通して定義する。
https://docs.microsoft.com/ja-jp/learn/modules/typescript-implement-interfaces/1-introduction
Propsというデータ型で、childrenとtitleを、それぞれReactNode型、String型で型を作っておく。
interface Props { children: ReactNode title: string }
typescriptを使ったコンポーネントの基本形。
ここで割り当てられているtitleのテキストは、デフォルトの値。
export const Layout: VFC<Props> = ({ children, title = 'Welcome to Nextjs', }) => { return ( <div> </div> ) }
また、リンクの箇所には
<Link href="/"> <a data-testid="home-nav" className="text-gray-300 hover:bg-gray-700 px-3 py-2 rounded" > Home </a> </Link>
として、このリンクが押されたかをテストで識別するために、aタグに「data-testid」で値を設定しておく。
全体は以下
import { ReactNode, VFC } from 'react' import Head from 'next/head' import Link from 'next/link' import Image from 'next/image' interface Props { children: ReactNode title: string } export const Layout: VFC<Props> = ({ children, title = 'Welcome to Nextjs', }) => { return ( <div className="flex flex-col justify-center items-center min-h-screen text-gray-600 text-sm font-mono"> <Head> <title>{title}</title> </Head> <header> <nav className="bg-gray-800 w-screen"> <div className="flex items-center pl-8 h-14"> <div className="flex space-x-4"> <Link href="/"> <a data-testid="home-nav" className="text-gray-300 hover:bg-gray-700 px-3 py-2 rounded" > Home </a> </Link> <Link href="/local-state-a"> <a data-testid="makevar-nav" className="text-gray-300 hover:bg-gray-700 px-3 py-2 rounded" > makeVar </a> </Link> <Link href="/hasura-main"> <a data-testid="fetchpolicy-nav" className="text-gray-300 hover:bg-gray-700 px-3 py-2 rounded" > fetchPolicy(Hasura) </a> </Link> <Link href="/hasura-crud"> <a data-testid="crud-nav" className="text-gray-300 hover:bg-gray-700 px-3 py-2 rounded" > CRUD(Hasura) </a> </Link> <Link href="/hasura-ssg"> <a data-testid="ssg-nav" className="text-gray-300 hover:bg-gray-700 px-3 py-2 rounded" > SSG+ISR(Hasura) </a> </Link> <Link href="/hooks-memo"> <a data-testid="memo-nav" className="text-gray-300 hover:bg-gray-700 px-3 py-2 rounded" > custom hook + memo </a> </Link> </div> </div> </nav> </header> <main className="flex flex-1 flex-col justify-center items-center w-screen"> {children} </main> <footer className="w-full h-12 flex justify-center items-center border-t"> <a className="flex items-center" href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app" target="_blank" rel="noopener noreferrer" > Powered by{' '} {/* <img src="/vercel.svg" alt="Vercel Logo" className="h-4 ml-2" /> */} <Image src="/vercel.svg" alt="Vercel Logo" width={72} height={16} /> </a> </footer> </div> ) }
次に、pages/index.tsxを編集
import { VFC } from 'react' import { Layout } from '../components/Layout' const Home: VFC = () => { return ( <Layout title="Home"> <p className="text-3xl font-bold">Next.js + GraphQL</p> </Layout> ) } export default Home
として、このリンクが押されたかをテストで識別するために、aタグに「data-testid」で値を設定しておく。
styles/Home.module.cssは使わないので削除。