React,Next.jsの覚え書き(設計手法なども含む)

コンポーネント名はパスカルケース(先頭は大文字)にする
〇:Text、Message
×:text、message

Reactフックについて

Next.jsの4つのレンダリング手法
- 静的サイト生成(SSG:Static Site Generation)
- getStaticProps、getStaticPaths
- クライアントサイドレンダリング(CSR:Client Side Rendering)
- サーバーサイドレンダリング(SSR:Server Side Rendering)
- getServerSideProps
- インクリメンタル静的再生性(ISR:Incremental Static Regeneration)

Next.jsでstyled-componentsをインストール
npm install styled-components@latest
npm install --save-dev @types/styled-components
注意
npm install styled-components
だとエラー
npm ERR! Cannot read properties of null (reading 'edgesOut')

ESLint(リントツール)とPrettier(フォーマッター)関連のライブラリ
- eslint
- prettier
- typescript-eslint
- @typescript-eslint/eslint-plugin
- @typescript-eslint/parser
- eslint-plugin-prettier
- eslint-plugin-react
- eslint-plugin-react-hooks
- eslint-plugin-import

storybookのインストール
npx storybook@latest init

storybook関連のライブラリ
- @storybook/addon-postcss
- tsconfig-paths-webpack-plugin
- @babel/ plugin-proposal-class-properties
- @babel/ plugin-proposal-private-methods
- @babel/ plugin-proposal-private-property-in-object
- tsconfig-paths-webpack-plugin
- @mdx-js/react

storybookを起動する
npm run storybook

マテリアルUI系のインストール
@mui/material
@mui/icons-material
@emotion/react
@emotion/styled

テスト環境構築
npm install --save-dev @testing-library/jest-dom @testing-library/react jest jest-environment-jsdom

2種類のルーター
App Router(新しい、推奨)
Page Router(古い)
From Pages to App

console.logが2回表示される?

Reactのインストール
npx create-next-app
next.jsのインストール
npx create-next-app@latest

コンポーネント設計
Presentational Component プレゼンテーショナル コンポーネント
見た目、デザインを実装するコンポーネント
//import './styles.css'
type ButtonProps = {
label: string
text: string
disabled: boolean
onClick: React.MouseEventHandler<HTMLButtonElement>
}
//ラベルとボタンを表示するコンポーネント
export const Button = (props: ButtonProps) => {
const { label, text, disabled, onClick } = props
//propsで渡されたデータを元に見た目を実装する
return (
<div className =" button-container">
<span>{ label }</span>
<button disabled={ disabled } onClick={ onClick }>
{ text }
</button>
</div>
)
}
export default Button
Container Component コンテナ コンポーネント
ビジネスロジックのみを実装するコンポーネント
import { useState, useCallback } from 'react'
import { Button } from './presentational-sample'
//ポップアップを表示するためのフック
const usePopup = () => {
//与えられたテキストを表示するポップアップを出現させる関数
const cb = useCallback(( text: string) => {
prompt( text )
}, [])
return cb
}
type CountButtonProps = {
label: string
maximum: number
}
//クリックされた回数を表示するボタンを表示するコンポーネント
export const CountButton = (props: CountButtonProps) => {
const { label, maximum } = props
//アラートを表示させるためのフックを使う
const displayPopup = usePopup()
//カウントを保持する状態を定義する
const [count, setCount] = useState(0)
//ボタンが押された時の挙動を定義する
const onClick = useCallback(() => {
//カウントを更新する
const newCount = count + 1
setCount(newCount)
if (newCount >= maximum) {
// アラートを出す
displayPopup(`You've clicked ${ newCount} times `)
}
}, [count, maximum])
//状態を元に表示に必要なデータを求める
const disabled = count >= maximum
const text = disabled
? 'Can\' t click any more'
: `You've clicked ${ count} times`
// Presentational Componentを返す
return (
<Button disabled={ disabled } onClick={ onClick } label ={ label } text ={text } />
)
}
export default CountButton

Atomic Design アトミックデザイン
Atoms
最小の要素。これ以上分割できない
例)ボタン、テキスト
Molecules
複数のAtomsを組み合わせて構築
例)ラベル付きのテキストボックス
Organisms
Moleculesよりも具体的な要素
例)入力フォーム
Templates
ページ全体のレイアウト
例)ページのレイアウト
Pages
ページそのもの
例)ページそのもの

サーバーコンポーネントとクライアントコンポーネントについて
サーバー コンポーネントとクライアント コンポーネントの決定を簡素化するために、クライアント コンポーネントの使用例が決まるまではサーバー コンポーネント (appディレクトリ内のデフォルト) を使用することをお勧めします。
「クライアントを使用する」ディレクティブ
指令"use client"_は、サーバー コンポーネント モジュール グラフとクライアント コンポーネント モジュール グラフの間の境界を宣言するための規則です。

Reactでは、
イベントを表すpropにonSomething、
イベントを処理する関数定義にhandleSomething
という名前を使うのが一般的です。

やっぱり公式はおさえておかないと

pops
useState
Context

API router

Next.jsでフォントを変更する方法

テクニック 即時関数の中でif文を実行する
<div>
{
//即時関数の中でif文を実行する
(()=> {
if( currentPos === 'main' ) {
return (<Main />)
} else if( currentPos === 'fontsize' ) {
return (<Fontsize />)
} else {
return ("コンポーネントがない!")
}
})()
}
</div>