React Hooksに対応した複数のonChangeハンドラを処理する書き方

Functional Componentにおける複数のonChangeハンドラを一元的に処理するコールバック関数をお伝えしたい。

まずフォーム項目の操作は、onChangeハンドラが必要で、記述がなければwarningが発生するケースもある。input要素を有するコンテンツに限れば、必須イベントハンドラといえる。

そしてinput要素がひとつということも考えにくく、複数のinput要素から構成されることが予想される。たとえばログインフォームにしても、メールアドレスとパスワード、ログイン保持などが考えられるが、そのどれもstate変化によって成り立つ。

すなわちonChangeハンドラが必要となるが、それぞれでコールバック関数を定義していては効率が悪い。複数input要素があっても、ひとつのコールバック関数が処理できれば、もっとも効率がよいというものだろう。

コールバック関数の書き方

さて主題が、React Hooksを活用したコンポーネントにおける複数onChangeハンドラを処理する書き方だった。

React Hooksでstate管理するならば、おのずとFunctional Component設計になる。React Hooksは、旬なアーキテクチャであるが、Class componentで設計しなければならないケースもあることだろう。

したがってFunctional componentとClass componentの書き方を用意することにした。興味があれば目を通してみてほしい。

Class component

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      user_name: "",
      email: ""
    };
    this.handleInputChange = this.handleInputChange.bind(this);
  }

  handleInputChange(e) {
    const target = e.target;
    const value = target.type === "checkbox" ? target.checked : target.value;
    const name = target.name;
    this.setState({
      [name]: value
    });
  }

  render() {
    const { user_name, email } = this.state;
    return (
      <>
        <input
          type="text"
          name="user_name"
          defaultValue={user_name}
          onChange={this.handleInputChange}
        />
        <input
          type="text"
          name="email"
          defaultValue={email}
          onChange={this.handleInputChange}
        />
      </>
    );
  }
}

Functional component

function App() {
  const [values, setValues] = useState({
    user_name: "",
    email: ""
  });

  function handleInputChange(e) {
    const target = e.target;
    const value = target.type === "checkbox" ? target.checked : target.value;
    const name = target.name;
    setValues({ ...values, [name]: value });
  }

  return (
    <>
      <input
        type="text"
        name="user_name"
        defaultValue={values.user_name}
        onChange={handleInputChange}
      />
      <input
        type="text"
        name="email"
        defaultValue={values.email}
        onChange={handleInputChange}
      />
    </>
  );
}

まとめ

Class component、Functional componentともに、大した差はないことが分かると思う。

イベントが発生したinput要素のname属性をstate名として、value属性をstate値として扱っている。果たして、stateを一元処理することになるわけである。

このエントリーが、あなたのクリエイティビティを刺激するものであると期待したい。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です