風待ち

プログラミングの勉強や日々の出来事のログなど

Reactでテーブルにテキストボックスを表示した時に一番最初の行のテキストボックスにフォーカスするには

業務用のシステムを開発していると、できるだけマウスやキーボードを使わずに使いたいという要望が多い。

ほとんどの場合はInputタグにautoFocus={true}を追加すればいいんだけど、ボタンを押すとテーブルが展開して詳細を入力していくような動きのある画面の時に、autoFocusが動作してくれなかった。

そこで、どうやったら表示された時にフォーカスがいくのかを調べた。

useRefを使うやり方でフォーカスさせる方法もあるけれど、配列からMAPでテーブルを作っていく時にはうまく動作させられなかったので、今回のようなやり方になった。

業務システムを実際に利用する人はパソコンやなんかになれている人は少ないので、こうしたちょっと操作を便利にするようなものは思ったよりも喜ばれる。

たいていこういう機能は開発の最後の方に作るので面倒に感じるけれどやっておいて損はないだろう。

import { useState } from "react";

type Item = {
  id: number;
  name: string;
};

function App() {
  const [list, setList] = useState<Item[]>([
    { id: 1, name: "foo" },
    { id: 2, name: "bar" },
    { id: 3, name: "baz" },
  ]);

  return (
    <table>
      <thead>
        <tr>
          <th>id</th>
          <th>name</th>
        </tr>
      </thead>
      <tbody>
        {list.map((v, i) => (
          <tr key={`list-${v.id}`}>
            <td>{v.id}</td>
            <td>
              <input
                type="text"
                value={v.name}
                // 一番最初の行のテキストボックスをフォーカスする
                ref={(e) => i === 0 && e?.focus()}
                onChange={(e) =>
                  setList(
                    list.map((value, index) =>
                      index === i
                        ? { ...value, name: e.target.value }
                        : value
                    )
                  )
                }
              />
            </td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

export default App;