キーワード検索45の記事がヒットしました。

鳥に生まれることができなかった人へ

復習のReact

基本的にJavaScriptで書くが、必要があればTypeScript版のコードを掲載する。

React18を対象にする

Next.jsなどのフレームワークは扱わない

Viteで環境構築する

コンポーネント

propsとstateはコンポーネントで値(状態 ≒ state)を扱う。propsは引数、stateはコンポーネントのローカル変数。

propsにはいろんな型の値を渡せる(プリミティブ & オブジェクト)。

const Child = (props) => {
  console.log(props)

  return (
    <>
      <p>id: {props.obj.id}</p>
      <p>name: {props.obj.name}</p>
    </>
  )
}

const App = () => {
  return (
    <Child obj={{ id: 1, name: "kento" }} />
  )
}

分割代入で受け取る。

const Child = ({ obj: { id, name }}) => {
  return (
    <>
      <p>id: {id}</p>
      <p>name: {name}</p>
    </>
  )
}

const App = () => {
  return (
    <Child obj={{ id: 1, name: "kento" }} />
  )
}

TypeScriptでの型定義。

const Child = ({ obj: { id, name }}: { obj: { id: number, name: string }}) => {
  return (
    <>
      <p>id: {id}</p>
      <p>name: {name}</p>
    </>
  )
}

useState

const App = () => {
  const [count, setCount] = useState(0)

  return (
    <>
      <p>count: {count}</p>
      <button onClick={() => setCount(count + 1)}>+1</button>
    </>
  )
}
type Book = {
  id: number,
  name: string
}

const books = [
  { id: 1, name: "kento" },
  { id: 2, name: "kouta" },
  { id: 3, name: "nao" },
  { id: 4, name: "miku" },
]

const Books = ({ books }: { books: Book[] }) => {
  return (
    <>
      {books.map(({id, name}) => (
        <Book id={id} name={name} key={id} />
      ))}
    </>
  )
}

const Book = ({ id, name }: Book) => {
  return (
    <>
      <p>id: {id}, name: {name}</p>
    </>
  )
}

const App = () => {
  return (
    <Books books={books} />
  )
}

stateの更新は非同期

const handleClick = () => {
  setCount(count + 1);
  setCount(count + 1);
};

このコードでは、setCount(count + 1) を2回呼び出しています。しかし、この場合、count は関数が呼ばれた時点の値 (すなわち現在の状態) を参照しています。

具体的な流れ 最初の setCount(count + 1) が呼ばれると、React は新しい状態を「現在の count + 1」に更新するようにスケジュールします。 2回目の setCount(count + 1) も、同じ現在の count を参照して「現在の count + 1」に更新するようにスケジュールします。 React は状態の更新をバッチ処理するため、結果として count は 1 増加するだけ になります。

const handleClick = () => {
  setCount((count) => count + 1);
  setCount((count) => count + 1);
};

このコードでは、setCount に アップデート関数 を渡しています。この関数は「前回の状態」を引数として受け取ります。

具体的な流れ 最初の setCount((count) => count + 1) が呼ばれると、React は現在の状態 (count) を基に「count + 1」を計算し、次の状態をスケジュールします。 2回目の setCount((count) => count + 1) が呼ばれると、React は 最初の更新後の状態 を引数として「count + 1」を計算し、次の状態をスケジュールします。 結果として、count は 2 増加 します。

違いの要点 コード1: count は関数が呼ばれた時点の値を直接参照しているため、複数の setCount 呼び出しは同じ値を基に処理されます。 コード2: count はアップデート関数の引数として渡される「最新の状態」を基に処理されるため、逐次的に更新されます。 推奨方法 状態更新が前回の状態に依存する場合は、コード2のようにアップデート関数を使用することを推奨します。これは、複数回の更新や非同期処理が絡む場合にも、意図通りの動作を保証できるからです。

コンポーネントが再レンダリングされるタイミング(詳しく書く)

  • stateが変化した時
  • propsが変化した時
  • 親コンポーネントが再レンダリングされた時

key属性

children

ReactNodeで型定義?

参考 : Reactのchildrenの型で子コンポーネントを制御する(したかった)

useEffect

https://www.cxr-inc.com/blog/cc98228bc2ba48d3853d077f25fb831c

https://tech.enechange.co.jp/entry/2024/06/28/100239

https://designare.jp/blog/tokuyasu/useeffect%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E3%81%B9%E3%81%8D%E5%A0%B4%E6%89%80%E3%81%AA%E3%81%AE%E3%81%8B.html

https://developer.mamezou-tech.com/blogs/2024/08/13/react_useeffect/

https://zenn.dev/ippe/articles/a53386986ff236

https://zenn.dev/yumemi_inc/articles/react-effect-simply-explained

https://tech.iimon.co.jp/entry/2024/07/02/152657

Transition

Suspense

自動バッチング

複数のステート更新を一回にまとめる機能。

17と18で何が変わるかの例示。

flushSyncの説明は不要。

参考

>Vueユーザー「あれ、ReactでonClickが動かない。。」のワケ - Qiita

strictモード

【React】Strictモードの挙動【バージョン18による】 #JavaScript - Qiita

useState

https://zenn.dev/counterworks/articles/putting-props-to-use-state

自動バッチング

新機能:自動バッチング React 18の新機能Automatic Batchingを理解する|デザミス株式会社 U-motion 開発チーム

Suspense

https://tech.anotherworks.co.jp/article/react-suspense-react18

SSR

https://blogs.jp.infragistics.com/entry/understanding-ssr