React TypeScript勉強メモ (union types,型アノテーション)
TypeScriptの基礎
number = 123
string = 'テキスト'
boolean = true(false)
undefind = undefind
null = null
union types
type List = string | number[];
Listの型は、string(文字列)か、number(数字)です。
と言いたいが配列がある場合は、必ずstringとnumberは()で覆わないといけない
type List = (string | number)[];
サバイバルTypeScriptより。
nullとは?
JavaScriptのnullは値がないことを示す値のこと。
画像があったら、画像を表示してね。
なかったら(null)、noimageを表示してね。
みたいな形で使われる。
nullリテラル
const x = null;
nullの型注釈
const x: null = null;
例題
// imagePathはmain-image.jpgのパスまたはnullとなると仮定
const imagePath: string | null = /* 何らかの方法で取得する処理 */;
if (imagePath) {
// imagePathがnullでない場合、main-image.jpgを表示
displayImage(imagePath);
} else {
// imagePathがnullの場合、noimage.jpgを表示
displayImage('noimage.jpg');
}
// 画像を表示する関数の例(この部分は実際のアプリケーションに合わせて変更する必要があります)
function displayImage(path: string): void {
// 画像を表示する処理をここに書く
console.log(`Displaying image: ${path}`);
// 例: 実際のHTMLでの表示
// const imgElement = document.createElement('img');
// imgElement.src = path;
// document.body.appendChild(imgElement);
}
変数宣言の型注釈 (type annotation)
変数にどんな値が代入可能かを指定できます。
const num: number = 123;
意味を教えると、数値型の定数 num を定義して、その初期値を 123 に設定しているということ。
例題
import React from 'react';
type ImageDisplayProps = {
imagePath: string | null;
};
const ImageDisplay: React.FC<ImageDisplayProps> = ({ imagePath }) => {
return (
<div>
{imagePath ? (
// imagePathがnullでない場合、main-image.jpgを表示
<img src={imagePath} alt="Main Image" />
) : (
// imagePathがnullの場合、noimage.jpgを表示
<img src="noimage.jpg" alt="No Image" />
)}
</div>
);
};
// 例として、ImageDisplayコンポーネントを使用する親コンポーネント
const App: React.FC = () => {
// imagePathはmain-image.jpgのパスまたはnullとなると仮定
const imagePath: string | null = /* 何らかの方法で取得する処理 */;
return (
<div>
<h1>Image Display App</h1>
<ImageDisplay imagePath={imagePath} />
</div>
);
};
export default App;
useEffectとuseStateを用いて、カウントアップを作ってみる
import React, { useState, useEffect } from 'react';
const Counter: React.FC = () => {
const [count, setCount] = useState<number>(0);
useEffect(() => {
// カウンターが変化するたびにこのブロックが実行されます
console.log('Count has changed:', count);
}, [count]); // countが変化したときにのみuseEffectを実行
const incrementByTwo = () => {
setCount(prevCount => prevCount + 2);
};
return (
<div>
<h1>Counter: {count}</h1>
<button onClick={incrementByTwo}>Increment by 2</button>
</div>
);
};
export default Counter;
useStateの記述について
const [count, setCount] = useState<number>(0);
そもそもこの1行はなにか?
count という状態変数を作成し、setCount を使ってその値を更新しています。
ボタンがクリックされるたびに count が増加し、Reactが再レンダリングされて新しい値が表示されます。
countが固定値。
setCountを用いて、どんどん更新していくようにする。
useStateのあとの<number>とは何か?
(0)は1とか2にしたらどうなる?
useEffectとは?
レンダリングについて
こちらの方の内容を抜粋して記載。
ブラウザレンダリングの流れについて
① Loading
② Scripting
③ Rendering
④ Painting
この順番の流れ。
Loading
HTML/CSS/js/jpegなどをダウンロードする
② Scripting
jsコードをエンジンに引き渡す。
コード→解析→コンパイル→実行
この流れで裏はおこなっている
③ Rendering
CSSをDOMで読み込む
CSSプロパティを算出した後、レンダリングエンジンはDOMツリー内全てのノードの視覚的なレイアウト情報の計算、レイアウトを行う。
Next.jsで利用するレンダリングについて
CSR(クライアントサイドレンダリング)
クライアントからレンダリングを行う。
クライアントからリクエストが送られる。
サーバーから空の HTML ファイル、CSS、JavaScript が返却される。
API を叩いて初期データを取得して HTML をレンダリング。
※WordPressの初期とかまさにこれ。
毎回クライアントからレンダリングするので、更新に時間がかかる。
初回ローディングが遅い
ユーザー体験は低い。
SSR(サーバーサイドレンダリング)
リクエストごとに更新されるレンダリング方法
2020年時点のブログでは、
・はてな
・LEGO
・audible
・Square Enix
・Mercari
などが静的ジェネレーターを用いているとのこと。
しかし、ISRの方がいいのでは?と思うことがあるので、現在使用されているかは不確か。
■順番について
クライアントからリクエストが送られる。
サーバーが API リクエスト
必要なデータを取得する
サーバー側で HTML をレンダリング
HTML/CSS/JavaScript をクライアントに返却
クライアントサイドで JavaScript が実行されてレンダリングされる。
SSG(スタティックジェネレーション)
よくコーポレートサイト、ブログなどで使用されるレンダリング方法
しかしリアルタイム更新が必要なものは、難しいレンダリング方法。
■順番について
API リクエスト
データ取得
静的ファイル生成
ISR (Incremental Static Regeneration)
段階的な静的サイト生成のこと。
ページにキャッシュの有効期限を指定することができ、有効期限が切れると、ユーザーがページにアクセスした際に、裏側でページの再ビルド(SSR)が行われてコンテンツが更新される。
再訪問時の、更新するレンダリングタイミングを設定できるのが強み。
リクエストごとに、レンダリングするとサーバー負荷になるのであればISRで設定することでサーバー負荷や費用削減にもつなげられる。
ただ大規模サイトにはビルドに時間がかかる。→Turbopackで解消済み?
レンダリングの流れ
クライアントからリクエストが送られる。
サーバーはリクエストされたページのデータを取得し、ページを生成します。 ここで生成されたページはキャッシュされて、次回以降のアクセスに利用されます。 また、有効期限を設定することが可能で、有効期限が切れたあとの一回は古いキャッシュを返して、裏側でページの再生成(SSR)を行います。
サーバー側で生成、またはキャッシュされた HTML を返却する。
ページが表示される
Discussion