UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【React】制御コンポーネントvs非制御コンポーネント

react-hook-formを調べていて、react-hook-formの特徴として非制御コンポーネントによってregister関数をrefで実行していることがわかった

uga-box.hatenablog.com

ただ、Reatが公式には制御コンポーネントを使うとことを推奨しているため、どっちがどういいのか?と思ったのでちょっと調べてみた

公式ドキュメントにはこの記事が参考にあるので読んでみる

goshakkk.name

非制御入力

非制御の入力は、従来のHTMLフォーム入力に似ていて、入力された値をrefを使用して取得できる

たとえばボタンのonClickハンドラーでは次のようになる

import React from "react";

export default function App() {
  const name = React.useRef()
  const handleSubmitClick = () => {
    console.log(name.current.value)
  }
  return (
    <div>
      <input type="text" ref={name} defaultValue="foo"/>
      <button onClick={handleSubmitClick}>Sign up</button>
    </div>
  );
}

この特徴として、必要なときにフィールドから値を「プル」する方法になる

また、React の state を経由しないので、入力時の再レンダリングしないですむ

制御入力

現在値と値を変更するためのコールバック関数をpropとして受けとる

Reactが推奨するやり方

import React from "react";

export default function Form(props) {
  return (
    <div>
      <input type="text" value={props.name} onChange={props.handleNameChange} />
    </div>
  );
}

入力値は、親コンポーネントのどこかでstateとして保存されている必要がある(もしくはreduxのような別のstore)

新しい文字を入力するたびに、handleNameChange が呼び出され、入力の新しい値を取り込んでstateを更新する

そこが更新されると新しい状態をもつようにFormコンポーネントが再レンダリングされる

このフローは、親コンポーネントからFormコンポーネントに対して「プッシュ」する方法になるためFormコンポーネントは要求せずとも、常に現在の入力値を持っている状態になる

パフォーマンスの反面、変更にすぐに応答できるので、入力中のバリデーションが可能になったりする

こういった特徴を理解し、状況に応じて選択するのがよさそう