Open18

Reactについて勉強していく

winnie279winnie279

Reactはどんなアーキテクチャ(MVC・MVVMなど)と言える?
Vue.jsはMVVMだし、ReduxはFluxだった。
hooks時代のReactはどんなアーキテクチャなのか?

winnie279winnie279

Reactは宣言的に表示するUI(宣言的UI)を作るだけのライブラリなので、アーキテクチャとは切り離して考える。どちらかというと、ステートの管理手法がアーキテクチャの話になる。

Vue.jsでもFluxとして使おうと思えば使えるかもしれないし、Reactも使うライブラリによってアーキテクチャは変わる。

#お困り相談会

winnie279winnie279

強いて言うならReactは単方向データフローのアーキテクチャで、Vue.jsは双方向データフローのアーキテクチャである。

#お困り相談会

winnie279winnie279

React Server Components(RSC)

コンポーネントをサーバーサイドのみで実行することが可能になった。関数単位でクライアント/サーバーサイドの実行を制御できるため、Streaming HTMLと相性が良い。Server Actionsも使える。

Next.jsのApp Routerは上記の流れを汲んだもの。

App Router

winnie279winnie279

ディレクトリ構成

  • Collocationにしたい(昨今の流れ&確かにそうだという感覚)。
  • 上位のコンポーネントはできるだけサーバーサイドにしたい。
  • サーバーサイドとクライアントサイドの処理を簡単に判別できるようにしたい。
  • (Remixが流行っていることを踏まえてワンちゃん移行が簡単にできるようにしたい 🐶 )
app/
  _components/ <-- 機能に依存しないコンポーネントはここ
    button.tsx: Button
  users/
    (list)/
      _logic/
        action.ts: action
        loader.ts: loader
      _view/
        userList.tsx: UserList
        deleteUserButton.tsx: DeleteUserButton
        newUserButton.tsx: newUserButton
      page.tsx: UserListPage  <-- server
      layout.tsx: UserListLayout
    [userId]/
      (info)/
        _logic/
          action.ts: action
          loader.ts: loader
        _view/
          userInfo.tsx: UserInfo
          deleteUserButton.tsx: DeleteUserButton
          editUserButton.tsx: EditUserButton
        layout.tsx: UserInfoLayout
        page.tsx: UserInfoPage  <-- server
      edit/
        _logic/
          action.ts: action
          loader.ts: loader
        _view/
          editUser.tsx: EditUser
          updateUserButton.tsx: UpdateUserButton
        layout.tsx: UserLayout
        page.tsx: UserPage  <-- server
    new/
      _logic/
        action.ts: action
        loader.ts: loader
      _view/
        newUser.tsx: NewUser <-- server or client
        saveUserButton.tsx: SaveUserButton
      layout.tsx: NewUserLayout
      page.tsx: NewUserPage  <-- server
  page.tsx: Page
  layout.tsx: Layout
  • page.tsx にはルーティングに専念してもらう。
  • ロジックとビューを分離しておき、 page.tsx_logic/ _view/ をそれぞれ呼び出す。
  • action.tsloader.ts はRemixのように切り出す。
winnie279winnie279

これでもいいかも

new/
  _components/
    saveUserButton.tsx: SaveUserButton
  action.ts: action
  layout.tsx: NewUserLayout
  loader.ts: loader
  page.tsx: NewUserPage  <-- server

もしくはこれ

new/
  _components/
    saveUserButton.tsx: SaveUserButton
  server.ts: action, loader
  layout.tsx: NewUserLayout
  page.tsx: NewUserPage  <-- server

最後のいいかもな
server.tsがロジックでpage.tsxがビューで分離できてるし

winnie279winnie279

フォームが送信されている間に保留中の状態を表示するために、ReactのuseFormStatusフックを使用することができます。

エラーハンドリング

データの再検証とリダイレクト

サーバーアクション内ではユーザーを検証する。

バリデーション

import server onlyがserver.tsで使えるかも?

winnie279winnie279

小技

input 要素の key を更新することで、意図的に defaultValue を更新する。

- <input defaultValue={value} />
+ <input key={value} defaultValue={value} />

setterの中身を関数にすることで、useStateを即座に更新する。

- setCount(count + 1)
+ setCount((count) => count + 1)
winnie279winnie279

Remix

winnie279winnie279

File Upload APIは4つ全部unstableっぽい。
multipart formを使うと、
・アップロードのプログレスを表示するなどが難しい。
・サーバーの実行時間がファイルサイズに依存する。