2023年11月19日日曜日

React&muiで、ダイアログオープン時にフォーカスを移す方法

かなり久しぶりに仕事でReactを使っています。最近はバックエンドとかモバイル通信網とかプロトコルの仕様書を読んで自分で実装したりとかどんどん低レイヤーな内容に寄っていたので、フロントエンドをやったのはかなり久しぶりな気がします。

muiでポチポチインターフェースを作っていたんですが、ダイアログを開いた時に中のコンポーネントにフォーカスを当てる方法で詰まりました。

あ、今日の内容はトラブルシューティングというよりReact/mui弱者の戯言だと思ってください。

アカンかったやつ

最初はこういうコードを書いていました。

export default function FooDialog(props) {
  const refFocus = React.useRef(null);
  React.useEffect(() => {
    if (!props.open) {
      return;
    }

    // 入力要素にフォーカスを当てる
    refFocus.current?.focus();
  }, [props.open])

  return (
    <Dialog open={props.open}>
      <TextField id="name" inputRef={refFocus} />
    </Dialog>
  );
}

しかし、待てど暮らせど一向にフォーカスは移らず。

イケたやつ

最終的には、こう書いたら動きました。

export default function FooDialog(props) {
  const refFocus = React.useRef(null);
  React.useEffect(() => {
    if (!props.open) {
      return;
    }

    // 入力要素にフォーカスを当てる
    setTimeout(() => {
      refFocus.current?.focus();
    }, 0);
  }, [props.open])

  return (
    <Dialog open={props.open}>
      <TextField id="name" inputRef={refFocus} />
    </Dialog>
  );
}

つまり、一旦CPUリソースを手放せばOK。

Reactってどうなの?

今回のメインの話は終わったのであとは余談なんですが、そもそもReactってどうなんでしょうか。

流行り廃りの激しいフロントエンド業界で10年もデファクトスタンダードの地位を保っているという凄まじい実績は誰も異論はないと思いますが、JSXでスタイルもマークアップもコードもごっちゃになってるのがあんまり好きじゃない・・・という人は一定数いるんじゃないでしょうか。まあワイもなんですが

「VueもSFCとかいう謎のファイルあるやんけ!」といわれたらまあその通り。ただアレはスタイルとマークアップとコードが一応ファイル内で分離はされてはいます。まあアレも微妙っちゃ微妙ですが。

0 件のコメント:

コメントを投稿