YmBIgo
@YmBIgo (和也 栗原)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

入れ子になった useState で 全角入力すると onChange が 3回飛ぶのはなぜなのでしょうか?

Mac で、下のようなコードで「全角入力→enter」すると onChange が 3回飛びます。

CodeSandbox にコードがあります ↓
https://codesandbox.io/s/nifty-sunset-49kyi2?file=/src/App.js:0-631

発生している問題・エラー

App.js
import React, { useState } from "react";

const App = () => {
  const [hoge, setHoge] = useState([]);
  return <HogeComponent hoge={hoge} setHoge={setHoge} />;
};

const HogeComponent = ({ hoge, setHoge }) => {
  const [inputValue, setInputValue] = useState("");
  const handleChange = (e) => {
    console.log(e.target.value);
    setHoge((prev) => [...prev, e.target.value]);
    setInputValue(e.target.value);
  };
  return (
    <div>
      <input value={inputValue} onChange={handleChange} />
      <ul>
        {hoge.map((h, index) => {
          return <li key={`hoge_${index}`}>{h}</li>;
        })}
      </ul>
    </div>
  );
};

export default App;

このフォームでフォームを全角入力するして「Enter」を押すと、3回 onChange が飛びます。
また、Windows だと 「Enter」の代わりに「左クリック」をしても 3回 onChange が飛びます。

console.log 出力例1
あ
""
あ
console.log 出力例2
あああ
ああ
あああ

onChange が 3回飛ぶ理由に、onChange内の setState の State の値を、HogeComponent 自身が参照しているからなことがあります。

→ 該当するソースコード

略式コード
import React, { useState } from "react";

const App = () => {
+ const [hoge, setHoge] = useState([]);
+ return <HogeComponent hoge={hoge} setHoge={setHoge} />;
};

+const HogeComponent = ({ hoge, setHoge }) => {
  const [inputValue, setInputValue] = useState("");
  const handleChange = (e) => {
    console.log(e.target.value);
+   setHoge((prev) => [...prev, e.target.value]);
    setInputValue(e.target.value);
  };
  return (
    <div>
      <input value={inputValue} onChange={handleChange} />
      <ul>
        {hoge.map((h, index) => {
          return <li key={`hoge_${index}`}>{h}</li>;
        })}
      </ul>
    </div>
  );
};

export default App;

ここで、なぜ3回も onChange が飛ぶのか説明できる方はいないでしょうか?
半角だと起きないので、composition などが関係するのでしょうか?
また、windows 環境での「全角入力→Enter」と「全角入力→左クリック」の入力方法の違いがわかる人はいるでしょうか?
どうぞよろしくお願いいたします。

0

1Answer

日本語変換中にもonChangeが飛ぶことはご存知かと思いますが,Windowsの場合確定前にフォーカスを外そうとすると,いったん変換中の文字列がすべて消えた後ペーストされるような挙動をするようです.
同じことがMacにおける変換でもいえそうです.

対策についてはちょっと考える体力がなかったので申し訳ありませんが,このへんにイベントの流れがまとまっていますので参考にしてみてください.
日本語変換のイベントはonCompositionStart等で取れるので,これを利用してあとからhogeの不要な部分を取り除いてもいいかもしれません.

割と関係ない話ですが,テキストボックスとhogeを表示する部分は,別コンポーネントに分けた方がよいと思われます.その方が再描画等の制御がしやすいです.

0Like

Your answer might help someone💌