【日報】Next.js チュートリアル

日報に書くこと
・学習時間
・学習内容
・学んだこと
・疑問に思ったこと
・明日やること

日報(9/13)
学習時間
3時間(コーディング:1.5時間)
学習内容
・pagesについて
・Link Component
・Assets, Metadata, and CSS
学んだこと
・pagesディレクトリ配下にjsファイルを配置するだけで、そのファイルへのパスがURLパスとなる
・Next.jsはリクエストしたページのコードだけを読み込むため高速
・本番ビルド:Linkコンポーネントがブラウザに表示されるたびに、Link先のコンポーネントをバックグラウンドでprefetchしているため、高速に描画することができる
・静的アセットはpubli配下に配置する
→pages同様にルートから参照できる
・next/imageコンポーネントを使用することで画像を最適化される
・デフォで遅延ロードされる
→ビューポートに入った時に読み込まれるため、画像によって表示速度が遅くなることはない
・CSSモジュールを使用することでコンポーネントレベルでCSSをスコープできる
→クラス名の衝突を機にする必要がない、異なるコンポーネントで同じクラス名を使用してもOK
疑問に思ったこと
・動的なルーティングはどうやって実現しているのか
→ダイナミックルーティングという方法で実現出来るらしいので、調べてみる
→とはいえ、バージョン13以降はapp routerに変わっているので、app routerの方を優先的にキャッチアップすべき、、?
明日やること
・ チュートリアルをPre-rendering and Data Fetchingの章まで進める
・ ダイナミックルーティングについて調べる

日報(9/14)
学習時間
3時間(コーディング1.5h)
学習内容
・Assets, Metadata, and CSS
・グローバルCSSについて
・Pre-rendering and Data Fetching
学んだこと
・CSSモジュールを使用するためには、末尾が.module.cssである必要がある
・CSS Modulesを使う限り、クラス名の衝突を心配する必要はない
・_app.jsをpagesディレクトリ直下に配置することで、全てのコンポーネントをラップすることになり、次のことができる
→ページ間を移動するときの状態保持
→global cssの追加
・pre-rendering = HTMLファイルを事前に生成しレンダリングすること
→静的生成とサーバサイドレンダリングの2種類がある
静的生成:ビルド時にHTMLを生成し、リクエストごとに再利用
サーバサイドレンダリング:リクエストごとにHTMLを生成
・静的生成(StaticSiteGeneration)においてgetStaticPropsを使用することで、この関数内部でデータを取得し、propsとしてページに送ることができる
・getStaticPaths()も一緒に使うことで、ダイナミックルーティングをさせることができる
・hydration=SSRでサーバサイドである程度DOMを構築して、ブラウザ側に返却する際に、イベントリスナーなどを行わないといけないため、そのような生きた状態に活性化することをhydrationという
・SSRはnode.js上で実行されるため、コンポーネント内で普通にwindowオブジェクトなどを使うとエラーになる
→使いたければ、useEffect内で使うようにする
・CSR, SSR, SSG, ISRについて下記サイトが簡潔でわかりやすかった
疑問に思ったこと
・全てのコンポーネントをラップするために配置するファイル名がなぜ_app.jsなんだろう?
・様々なレンダリング方法が用意されており、特徴やどういう時に使うかはわかったが、実際のPJではどのように使い分けているのか
明日やること
・Dynamic Routesセクション
今日のコミット
getStaticPropsとglobal.css
dynamic routesのgetStaticPathsの実装まで

日報(9/15)
学習時間
2.5時間(コーディング:1h)
学習内容
・Dynamic Routesについて
学んだこと
それぞれは下記レンダリング用のAPI
- SSG:getStaticProps, getStaticPaths
- SSR:getServerSideProps
・getStaticPathsは下記のような、paramsキーを持ちidキーを持つオブジェクトを含んでいる必要がある(ファイル名に[id]を使った場合)
[
{
params: {
id: 1
}
},
{
params: {
id: 2
}
}
]
・キャッチオールルート
→もう少し詳細に調べたい
・Next.jsのエラーについて
→Linkコンポーネントでタグの配置をミスっていてエラーが出たが、Nextのエラーの見方がわからず、原因特定までかなり時間がかかった。
→書くコードが何をしているのかがまだまだ理解できないないので、少しずつ解像度を上げていく必要があると痛感、、
疑問に思ったこと
・Next.jsのエラーの見方(正直Vueと比べて見にくいと感じた。。)
→とはいえエラーは確実に見れるようにならないといけないので、都度都度エラーを読んだりググったりして、Nextのエラーに慣れていく
明日やること
・API Routs
・余裕あればデプロイのセクションまで
今日のコミット
調べること
・getStaticProps
・getStaticPaths
下記記事が個人的にわかりやすかった
→各APIについてで簡単にまとめられていてわかりやすかった
→各レンダリングも含めて

日報(9/16)
学習時間
3時間(コーディング:2h)
学習内容
・API Routsについて
・Deploy
・TypeScriptの導入
学んだこと
API Routesについて(調べた内容のメモ)
・API Routes経由でDBにアクセスすることができる
・serverless functionとしてデプロイされる
・作成した関数は必ずexportする必要がある
・フロント側からAPI Routesにアクセスし取得したデータをブラウザに表示させることができる
→pages/api/users.jsとpages/users.jsのような感じ
・getServerSidePropsを使用して、サーバサイドからpages/api/users.jsにアクセスすることもできる
→この場合fetch関数の引数には、絶対パスを設定する必要がある
・Dynamic Routesにも対応している
→pages/api/users/[id].jsのようにすることで実現できる
・Next.jsでの開発にはDPSと呼ばれるワークフローで行うことが強く推奨されている
Develop→Preview→Ship(mainにマージし、本番環境デプロイ)
・Next.js固有の方としてそれぞれ下記が用意されている
【SSG, SSR】
getStaticPaths : GetStaticPaths
getStaticProps : GetStaticProps
getServerSideProps : GetServerSideProps
【API Routes】
import { NextApiRequest, NextApiResponse } from 'next'
export default (req: NextApiRequest, res: NextApiResponse) => {
// ...
}
疑問に思ったこと
・実際のPJではどのくらい厳密に型チェックを行っているのか
・React.ReactNodeとは
明日やること
・チャットアプリを作成する環境のセットアップ
今日のコミット
明日調べること
・キャッチオールルート
・AppPropsとは?
・TSのasについて
・React.ReactNodeとは
記事投稿しました(どちらも同じ内容ですが。。)

日報(9/17)
学習時間
3時間(1h)
学習内容
・TSのasについて
・React.ReactNodeとは
・Chat App向けのリポジトリの作成
・firebaseのセットアップ
PJの作成→アプリにfire baseの追加→realtime DBの作成→firebase authenticationの設定
学んだこと
・React NodeとはReactの要素を表現するための用語で、Reactのコンポーネントツリーを形成する
次のいずれかの型を持っている
- boolean
- null
- undefined
- number
- string
- ReactElement(Reactコンポーネント自体)
- ReactFragment(複数の要素をまとめる)
- ReactPortal(レンダリングされるDOMを特定の場所に設定する)
- Array<React Node>
・TSのasについて
→型アサーション
すでに型定義済みの変数の型を上書きする
とはいえ、型アサーションは多様しないほうが良い
疑問に思ったこと
・Chat Appを作るにおいて、どのようなディレクトリ構成にするのが良いか
明日やること
・Chat Appのログイン機能
今日のコミット
調べること
・キャッチオールルート
・AppPropsとは?

日報(9/18)
学習時間
3時間(コーディング:2h)
学習内容
・fire base authenticationを使ったGoogleログイン機能の実装
・キャッチオールルートとは?
学んだこと
・Googleアカウントを用いたログイン機能の実装方法
→ログインが成功した後の画面遷移や、ログイン中かの判定をどう実装するのかは考える必要がある
・MUIのスナックバーの使い方
・キャッチオールルート
→ルーティングを動的に行うためのものだが、いまいち理解できなかったのでもう少し調べる
疑問に思ったこと
・一般的にログイン機能はどう実装されているのか
→各種SNSなどのアカウントを用いたものやメアドとパスワード形式のものなど様々なものがあるが、実際の処理や状態管理など
明日やること
・ログインしているかに応じて、表示する画面を切り替える実装
・ログアウト機能
今日のコミット
調べること
・キャッチオールルート
・一般的にログイン機能はどう実装されているのか
→またその状態管理なども

日報(9/19)
学習時間
2.5h(コーディング:1h)
学習内容
・ログイン状態に応じた、表示するコンポーネントの切り替え
・ログアウト機能
学んだこと
・fire baseのonAuthStateChangedを用いてログイン状態を監視する方法
→storeを使った方法もキャッチアップしておきたい
・_app.tsx内をAuthProviderでラップすることで、各コンポーネントから認証情報を取得できるようになる
・firebase/authからsignOut, getAuthをimportし、getAuthで取得したauth情報をsignOutの引数で渡してあげることでログアウトさせることができる
・App Routerについて下記記事がPage Routerとの違いを示しながら解説しており、理解しやすかった
疑問に思ったこと
・firebaseのgoogle認証がローカルだと使えていたが、vercelにデプロイすると使えなくなった
明日やること
・ログアウト機能のつづき
・Vercelにデプロイすると、Googleログインができなくなったため修正
今日のコミット
調べること
・なぜfirebaseのGoogle認証がvercel上で使えなくなったのかと、修正方法

日報(9/20)
学習時間
3h(コーディング:1.5h)
学習内容
・vercelにデプロイすると、firebaseのgoogle認証が動かなくなったので修正
・ログアウト機能の続き
学んだこと
・本番環境において、アクセス許可や環境変数の設定が必要(本番環境における認証機能の修正)
・本番環境において、firebaseでアクセスを許可していないと、認証機能が利用できない
・Vercelに環境変数を追加する必要がある(firebaseの環境変数)
・vercelはプルリクごとにプレビュー用のURLが生成してくれる
疑問に思ったこと
・今は特にroutingを使用していないが、routingさせたほうが良いのか
→現状:routingではなく、ログインしているかによって表示するコンポーネントを切り替えている
→疑問:ログイン状態に応じて、表示するコンポーネントを切り替えるのではなく、routingでページを切り替えたほうが良いのか
明日やること
・チャット画面の作成
今日のコミット
調べること
・vercelについて

日報(9/21)
学習時間
3h(コーディング:1.5h)
学習内容
・チャット画面の作成
・チャットをrealtimeDBに書き込む処理の雛形作成
学んだこと
・Realtime DBについて
DBに書き込むメソッドにはpush(), set(), update(), transaction()のがある
基本的にpush()をOKだと思う
次のような形でデータを書き込むことができる
import { getDatabase, push, ref } from "firebase/database";
import { FirebaseError } from "firebase/app";
const db = getDatabase()
const dbRef = ref(db, 'room')
await push(db, {
title: 'タイトル',
body: 'メッセージ',
})
次のようにすることで全件参照することができる
const db = getDatabase()
const dbRef = ref(db, 'room')
return onChildAdded(dbRef, (snapshot) => {
const value = snapshot.val()
setChats((prev) => [...prev, { message: value.message }])
}
疑問に思ったこと
・ログイン後画面をリロードすると、一瞬ログイン画面が表示されてしまうが、どうすればログイン画面が表示されないようになるか
→試したいことはあるのでまずは一旦試してみる
明日やること
・チャットデータをリアルタイムで取得する処理
・DBとの繋ぎこみ
今日のコミット
チャット画面の雛形を作成
送信ボタンを押すと、入力内容がコンソールに表示されるまで
調べること
・vercelについて

日報(9/22)
学習時間
3h(コーディング:1h)
学習内容
・チャットデータをリアルタイムで取得する処理
・DBとの繋ぎこみ
学んだこと
・データの取得
→firebaseのデータはsnapshotという形で取得することができる
snapshot.val()で値が取得でき、型はanyとなる
・useStateで配列にデータを追加するには下記のようにする
→setData([...prevData, data])
疑問に思ったこと
・普段型をつけたりしないため、どう型をつけていけば良いのか
・なぜかDBから受け取ったチャットが無限に増えてしまう(おそらくなぜかmapが無限に実行されている)
明日やること
・propsとして子コンポーネントに渡しているデータに型をつける(できる限り他の箇所も)
今日のコミット

日報(9/23)
学習時間
3.5h(コーディング:2h)
学習内容
・DBから受け取ったチャットが無限に増えてしまう不具合修正
学んだこと
・DBから受け取ったチャットが無限に増えてしまう不具合修正
→useEffectの使い方が良くなかった
第2引数にuseStateで更新したいデータを入れていたが、useState内で下記のようにすることで解決
const [chat, setChat] = useState<chatType[]>([])
useEffect(() => {
// code...
const data = fetchData()
setChat((v) => [...v, data])
}, [// 当初ここにchatを入れていたため不具合が起きていた])
・useEffectについて
→マウント時に2回実行されることがある
下記記事のようにすることで、対処可能
・next/imageコンポーネントのsrcに対して外部URLを設定するときの注意点
→next.confgi.jsに使用する外部ドメインを設定しておく必要がある
const nextConfig = {
images: {
domains: ['XXX.com']
}
}
module.exports = nextConfig
疑問に思ったこと
・useEffectを使ったログイン状態の確認をしている処理が2回走っているようだが、
どうすれば無駄な処理が走らないようになるか
明日やること
・スタイルの修正続き
・ディレクトリ構成の見直し(できればやりたい)
今日のコミット

日報(9/24)
学習時間
2h(コーディング:1.5h)
学習内容
・スタイルの修正
・ヘッダーの修正
・デプロイ環境の動作確認
学んだこと
・classNameを複数付与する方法
→className={${name1} ${name2}
}(テンプレートリテラルの書き方で普通にできた)
・アプリ内で使用するメインカラーを決めて、色を多用しないこと
→色の競合などを確認する際に使える
https://color.adobe.com/ja/create/color-wheel
・色、大きさ、形状などで強弱をつける
疑問に思ったこと
・デザインを考えるのが難しい(どうやデザインしていけば良いのか)
→最低限のデザイン・UI/UXの知識はキャッチアップしないといけない
明日やること
・リロード時にログイン画面が表示されてしまう原因調査(修正までしたい)
・ログイン画面とチャット画面をroutingで表示するように(↑が終わり次第)
・デザインのブラッシュアップ続き
今日のコミット

日報(9/25)
学習時間
2h(コーディング:1h)
学習内容
・リロード時にログイン画面が表示されてしまう原因調査
→おそらくユーザ情報が取得される前に、コンポーネントがレンダリングされているため
→修正方法が分からなかったので、引き続き調べたい
・useStateで定義している変数に対して型の付与
・コード整理
・見た目を少し修正
学んだこと
・リロード時にログイン画面が表示されてしまう原因調査
→NextAuth.jsやReduxでstoreで管理するなどすれば解決できるかも?
→せっかくならこのタイミングでキャッチアップしておきたい
・useStateで定義している変数に対して型の付与
→const [text, setText] = useState<string>('')
疑問に思ったこと
・どうすればユーザ情報が取得されてkらコンポーネントがレンダリングされるようになるか
明日やること
・リロード時にログイン画面が表示されてしまう件の修正方法の調査
(→nextAuth, Reduxについても調べる)
・アプリ全体の確認と必要に応じて修正
今日のコミット

日報(9/26)
学習時間
2h(コーディング:45m)
学習内容
・useStateについて
・認証情報が取得されてからコンポーネントをレンダリングさせる方法
学んだこと
・useStateについて
→useStateにおけるsetXXのような更新関数は非同期的に動作する
そのため複数回続けて呼び出しても、それぞれの呼び出しは前の状態の値を参照する
→すべて同じ値を参照しているため、1回呼び出したときと結果が変わらない
→setXXの引数に関数を与えてやることで解決可能
例:
const handleClick = () => {
setCount((prev) => prev + 1)
setCount((prev) => prev + 1)
setCount((prev) => prev + 1)
}
・認証情報が取得されてからコンポーネントをレンダリングさせる方法
→帰りが遅く、あまり試せなかったため明日以降引き続き修正していく
疑問に思ったこと
今日は特になしです
明日やること
・インターンで、双方にとって充実した1日にすること
今日のコミット
デプロイしようとしたらvercelの障害でQueに入れられたみたい。。。