Next.jsの歩き方
変更からデプロイまで
1.ローカルテスト
npm run dev
2.コードのステージング
git add .
3.リポジトリにコミット
git commit -m "説明文"
4.リモートリポジトリにプッシュ
git push
5.本番にデプロイ
vercel --prod
Next.js (JavaScript/TypeScript) に Chakra UI を導入する方法
chakra-ui
TypeScriptの導入
途中から追加する場合
・ルートにtsconfig.jsonを作成
・TypeScriptとその他の必要なtypesをインストール
npm install --save typescript @types/node @types/react @types/react-dom @types/jest
・tsconfig.jsonが更新されている事の確認。
・.jsを.tsxに変更して動作する事の確認。
useEffect
マウント時に一回だけ実行useEffetct
に渡されるコールバック関数を、コンポーネントのマウント時に1回だけ実行するには、第2引数に空の配列を渡します。
useEffect(() => { ... }, []);
useEffect
の第2引数に配列を渡すと、マウント時とその要素に変更があった場合にコールバック関数を実行するように動作します。
例えば何らかのid
に変更があった場合に、API通信してデータを取得する、などの使い方ができます。
const [id, setId] = useState(0);
useEffect(() => { ... }, [id]); // idに変更があった場合に、コールバック関数を実行する。
プログレスバー
npm install nextjs-progressbar
/pages/_app.tsx
import NextNprogress from 'nextjs-progressbar'
<NextNprogress />
CSS
import styles from "../../styles/home.module.scss";
<div className={styles.contain}></div>
複数の場合
<div className={`${styles.class1} ${styles.class2}`}></div>
html内で直接スタイルを書く
<div style={{ backgroundColor: `lightGray` }} ></div>
キーボードイベント
const handleKeyDown = (event: KeyboardEvent) => {
// Escapeキーの場合処理を行う
if (event.key === "Escape") {
console.log("keydown Escape Key");
}
};
useEffect(() => {
document.addEventListener("keydown", handleKeyDown, false);
}, []);
oauth接続
npm info next version = 12.1.6
//pages/api/auth/[...nextauth].js
import axios from "axios";
import NextAuth from "next-auth";
import GithubProvider from "next-auth/providers/github";
import GoogleProvider from "next-auth/providers/google";
import { signIn } from "next-auth/react";
// prisma adaptor 使って、user データ、認証データを永続化する
// import { PrismaAdapter } from "@next-auth/prisma-adapter";
// import { PrismaClient } from "@prisma/client";
// const prisma = new PrismaClient();
const { GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, NEXT_PUBLIC_SECRET } =
process.env;
// if (!GOOGLE_ID) throw new Error("You must provide GOOGLE_ID env var.");
// if (!GOOGLE_SECRET) throw new Error("You must provide GOOGLE_SECRET env var.");
const setting = {
// adapter: PrismaAdapter(prisma),
providers: [
GoogleProvider({
clientId: GOOGLE_CLIENT_ID,
clientSecret: GOOGLE_CLIENT_SECRET,
}),
],
callbacks: {
async signIn({ user, account, profile, email, credentials }) {
console.log("サインイン");
return true;
},
async jwt({ token, user, account, profile, isNewUser }) {
console.log(`アカウント:${JSON.stringify(account)}`);
return token;
},
},
// callbacks: {
// emailのドメイン制限を入れたい場合は以下のcallbacksを入れてください
// signIn: async (user, account, profile) => {
// if (
// account.provider === "google" &&
// profile.verified_email === true &&
// profile.email.endsWith("@example.com")
// ) {
// return Promise.resolve(true);
// } else {
// return Promise.resolve(false);
// }
// },
// },
// ここに NEXTAUTH_SECRET を入れる?
secret: NEXT_PUBLIC_SECRET,
};
export default (req, res) => NextAuth(req, res, setting);
nextauthでprisma.adapterを使う場合はschema.prismaに下記が必要
※prisma.adapterを使えばログイン情報が自動保存される
※nextauthの公式と違うのが気になるけど試してない 公式
model Account {
id String @id @default(cuid())
userId String @map("user_id")
type String
provider String
providerAccountId String @map("provider_account_id")
refresh_token String? @db.Text
access_token String? @db.Text
expires_at Int?
token_type String?
scope String?
id_token String? @db.Text
session_state String?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([provider, providerAccountId])
@@map("accounts")
}
model Session {
id String @id @default(cuid())
sessionToken String @unique @map("session_token")
userId String @map("user_id")
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@map("sessions")
}
model User {
id String @id @default(cuid())
name String?
email String? @unique
emailVerified DateTime? @map("email_verified")
image String?
accounts Account[]
sessions Session[]
@@map("users")
}
開発用env
.gitignoreに含めてアップしないようにする
//.env.local
コマンド叩いて値を取る
NEXT_PUBLIC_SECRET=# Linux: `openssl rand -hex 32` or go to https://generate-secret.now.sh/32
NEXTAUTH_URL=http://localhost:3000
こっちがfirebase
GOOGLE_CLIENT_ID=xxx
GOOGLE_CLIENT_SECRET=xxx
本番用env
Vercelなどのホスティングサービスにアップする
参考サイト
NextAuth.jsを使ったGoogle認証機能+データベース(Prisma)の設定の理解
NextAuth.js公式フロー
Twitterの認証
readmeに記入
無限スクロール
import {useState} from 'react';
import InfiniteScroll from "react-infinite-scroller"
export default function Index() {
const [list, setList] = useState([]); //表示するデータ
const [hasMore, setHasMore] = useState(true); //再読み込み判定
//項目を読み込むときのコールバック
const loadMore = async (page) => {
const response = await fetch(`http://localhost:3000/api/test?page=${page}`); //API通信
const data = await response.json(); //取得データ
//データ件数が0件の場合、処理終了
if (data.length < 1) {
setHasMore(false);
return;
}
//取得データをリストに追加
setList([...list, ...data])
}
//各スクロール要素
const items = (
<ul>
{list.map((value) => <li>{value}</li>)}
</ul>);
//全体のスタイル
const root_style = {
marginLeft : "50px",
marginTop : "50px",
}
//ロード中に表示する項目
const loader =<div className="loader" key={0}>Loading ...</div>;
return (
<div style={root_style}>
<InfiniteScroll
loadMore={loadMore} //項目を読み込む際に処理するコールバック関数
hasMore={hasMore} //読み込みを行うかどうかの判定
loader={loader}> {/* 読み込み最中に表示する項目 */}
{items} {/* 無限スクロールで表示する項目 */}
</InfiniteScroll>
</div>
)
}
GOOGLE_CLIENT_SECRET=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