SyntheticEventと非同期(setState)


次のコードはcustom hookです.
formを処理するコンポーネントでは、入力を管理する機能を組み合わせて定義します.
import { useState, useCallback } from "react";

const useInput = (initialInput) => {
  const [input, setInput] = useState(initialInput);

  const onChangeInput = useCallback((e) => {
    // const { name, value } = e.target;
    console.log(e);
    setInput((input) => {
      return {
        ...input,
        [e.target.name]: e.target.value,
      };
    });
  }, []);

  return [input, onChangeInput];
};

export default useInput;
ただし、inputを作成すると、次のようなエラーが発生します.

  • 検索エラーのStackoverflow回答

  • 次の図のように変更すると、問題が解決されることがわかります.
    しかし、原因を理解していないので、探すことにしました.

    synthetic Event


    reactでは、イベントハンドラがSynthectionEventオブジェクトを使用してブラウザ内のイベントを囲み、すべてのブラウザで同じ操作を行うことを確認します.
    しかし、この相手の働き方は不思議だ.
    パフォーマンスのメリットを得るために、オブジェクトは引き続き繰り返し使用されます.
    これをevent poolingといいます.△次のバージョンの反応から消えるそうです.
    簡単に言えば、イベントハンドラは常に実行され、その後、SynthectionEventオブジェクトのすべての要素がnullifyにクリアされます.

    办公室的说明链接


    この操作方法を説明するために、react公式サイトには以下の内容があります.
    function handleChange(e) {
      // This won't work because the event object gets reused.
      setTimeout(() => {
        console.log(e.target.value); // Too late!
      }, 100);
    }
    すなわちsettimeoutのe.targetです.valueは、必要なオブジェクトを指定しません.

    答えが見つかった。


    反応の中で
  • setStateは非同期運転の
  • である
  • システムイベントは、object poolingで再利用され続けます*
    *つまり、イベントハンドラが起動すると、オブジェクト内部のコンテンツが初期化されます.
  • どちらの方法も上部から確認できるエラーを示しています.
    したがって、まずその値を別の変数に割り当てます.
    指定した値を使用してstateを変更すると、エラーがなくよく動作していることがわかります.