【初心者】React、Next.js でつまづいたところ等のメモ
TypeScriptでうまくいかなかったメモ
自作のコンポーネントは大文字で始めないといけない。
x myheader
o Myheader or MyHeader小文字で始めるとタグとして使おうとしたときに 「プロパティ " myheader " は 型 " JSX.IntrinsicElements " に存在しません。」と怒られる。
引用:https://zenn.dev/tsumayoji/scraps/dfceb4b4db11a7
この記事見つけてなかったら詰んでた。
Reactでフォーム作りたい
非制御コンポーネントか制御コンポーネントで書く
メリットデメリットを見た感じ、今回の実装で「入力するたびに render する」必要ないから非制御で。
React Hook Formが記事多いし、詳しくは書いていくうちに理解
React Hookの使い方
編集、保存でフォームの表示を切り替えたい
if文で切り替える
詰まった
何個もフォーム作るから、使いまわしたい
解決策
子コンポーネントに骨を作り、親から身のprops渡す
詰まった
Next.jsに環境変数の追加方法
解決策
Node.js の process.env
による環境変数の参照が有効なのは、基本的には次のようなサーバーサイドで実行されるコード内のみです。
- ビルド時あるいはアクセス時に呼び出される
getStaticPaths
やgetStaticProps
- 必ずアクセス時に呼び出される
getServerSideProps
- 必ずアクセス時に呼び出される API ルートのハンドラ関数 (
handler
)
詰まった
setStateでsetしたのにstateの中身が見れない
→ネストされた関数内でsetStateして、stateの中身を見ようとしたらエラー吐いた。setTimeout使って中身を見ると見れたので、setされるのが遅いのが分かった。
解決策
hookが使えるのは
- 関数コンポーネント・カスタムフック内
- トップレベルのみ(ループや条件分岐・ネストされた関数内で呼び出してはいけない)
でしか呼び出せない。
mapの中身をforみたいにループで表示
keyを指定しないとダメだが、keyをindexにするとまずい
useStateとuseEffectの実行タイミング
Linkコンポーネントにaタグをつける理由
→セマンティックなコードにして、SEOを上げるため
三項演算子の条件分岐で、ボタンのクラス名を切り換えたりできる。
<button>
<div className={ primary ? 'primaryButtonInner' : 'normalButtonInner' }>{label}</div>
</button>
コンポーネントの粒度どうする?タグごと?
コンポーネント指向のデメリットは、コンポーネントを分ける粒度、分け方が開発者によって異なる、ということです。そのため、少し時間をかけてすり合わせをしていく必要があります。
コンポーネントの粒度はAtomic Designの思考を取り込む。
ただし、鵜吞みにせず、規模に応じてカスタマイズしよう。
対応策として、Atomic Designの思想を取り込んでプロジェクト内でコンポーネント分割の考え方を最適化するという方法があります。Atomic Designもすべてに対して最適解ではないので、サービスや規模に応じてカスタマイズしていくのが良いと思います。
(雲)
フォームをDBに送り、DBがあれば二個目のフォームを表示する」機能を作ってた。
DBを確認するには、リロードしなければいけなかった。
(雨)
リロードするjs,reactの関数ないかな。と探した
(傘)
よくよく考えたら、SPAなのに再レンダリングとか無駄すぎってなった。
開発環境でリロードすると、
Next.jsは開発モード(npm run devあるいはyarn dev)で起動する場合、SGの画面もSSR(Server-side >Rendering)となります
だから、
Error: Hydration failed because the initial UI does not match what was rendered on the server.
のエラーは、一旦リロードしてリクエストを送った時に発生する。(保存するだけじゃ出ない)
なぜなら、リクエストを送って、プレレンダリングさせることで、「プレレンダリングしたもの」と「実際に描画されたもの」を比較し、出現するから。
コンポーネント内でgetServerSidePropsをしたかった。
結論できない。
公式ドキュメントでもPagesで呼べって言ってる
npm run startやdevの違いってなんやろ
"scripts": {
"dev": "next dev",
"build": "next build && next export",
"start": "next start"
},
next devとかを呼んでる。
- next dev - next は Next.js を開発モードで実行します。
- next build - next build は本番用にアプリケーションをビルドします。
- next start - next start は Next.js の本番サーバーを起動します。
- next lint - next lint は Next.js に組み込まれた ESLint の設定をします。
devとかstartの仕組み
tailwindについて
tailwindのメリット
コンポーネント志向で発揮する
(例)profileに酷似したarticleコンポーネントを作ろうとしたとき
-
従来
- profileをlistItemにして二つに適応
- 結局分ける羽目に。名前が被る。
- profileと酷似したarticleというCSSを作成
- DRY(don't repeat yourself)の原則にのっとらないコード
- profileをlistItemにして二つに適応
-
tailwindを使えば
- コンポーネントごとにCSS効かせて、あらかじめ分ける
- クラス名を考えないでいい
- DRYだが、記述量が少なく、開発が進み、繰り返しのパターンが明確になった任意のタイミングで抽象化出来るためOK
- (別件)コードに一貫性を持たせられる
凡ミス集
たまにある。({name})を(name)にしたり
map のreturnを忘れない、、、!!!
arr.map((data, i) => data[i])
// もしくは
arr.map((data, i) => {
return data[i]
}
オブジェクトのままrenderして表示させようとしていたらエラー
Objects are not valid as a React child (found: object with keys {name}).
If you meant to render a collection of children, use an array instead.
「オブジェクトはReactの子としては無効です(見つかった:キーが{STATUS_TEXT}のオブジェクト)。
子のコレクションをレンダリングする場合は、代わりに配列を使用してください。」
ちゃんとオブジェクトのフィールドを表示させる。
import React,{useState} from "react";
import {taskStatusText} from "../component/taskStatusText "
export const Hoge =(status) => {
const [statusValue,setState] = useState(taskStatusText(state.task.order_status))
return(
<div>
{/* {statusValue} のようなオブジェクトは表示できない*/}
{statusValue.STATUS_TEXT}
</div>
)
}
カレンダー作りたい
date-fnsの関数(Weekend, Month等)を活用して、楽かつ、コードを見やすく書けばOK
CDNや<script>で呼ぶようなサードパーティの呼び出し方
きっかけ
これを試そうとしてた
対処法
<Script
src="https://apis.google.com/js/api.js"
strategy="beforeInteractive"
/>
<Script
src="https://accounts.google.com/gsi/client"
strategy="beforeInteractive"
/>
メアドごとにカレンダーの予定を取得する
認証周りの関数