かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

React Warning: A component is changing an uncontrolled input になったとき

React で form を作っていたら次のような Warning が発生しました。

Warning: A component is changing an uncontrolled input of type text to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component

長い…

React のフォームパーツには controlled と uncontrolled があり、コンポーネントが有効な状態でこれが切り替わるのはダメということで、今回は controlled なフォームが uncontrolled に変更されている事が問題のようです。

controlled と uncontrolled

HTML では <input><textarea>、そして <select> のようなフォーム要素は通常、自身で状態を保持しており、ユーザの入力に基づいてそれを更新します。React では、変更されうる状態は通常はコンポーネントの state プロパティに保持され、setState() 関数でのみ更新されます。
React の state を “信頼できる唯一の情報源 (single source of truth)” とすることで、上述の 2 つの状態を結合させることができます。そうすることで、フォームをレンダーしている React コンポーネントが、後続するユーザ入力でフォームで起きることも制御できるようになります。このような方法で React によって値が制御される入力フォーム要素は「制御されたコンポーネント」と呼ばれます。
cf. React フォーム 制御されたコンポーネント

つまり input タグなどの value が React の state で管理されていて setState で変更されるコンポーネントが controlled で、そうでないものが uncontrolledコンポーネントということのようです。

state で controlled にしているフォームパーツで warning が発生してしまう場合

今回は下記のようなフォームで warning が発生していました。

function Input() {
  const [value, setValue] = useState();
  return (
    <input change={(e) => setValue(e.target.value)} value={value} />
  );
}

一見 state で value が制御された controlled なコンポーネントのように見えますが、フォームの値を変更したりすると Warning: A component is changing an uncontrolled input な警告が発生してしまいます。

State が null, undefined になる場合がある

フォームコンポーネントは State が null または undefined になると uncontrolled になるようで、初期値が設定されていないフォームコンポーネントは一見して問題がないようにみえてもこの Warning が発生してしまうようです。

先のフォームの場合は useState()useState('') のように修正すればOK

function Input() {
  const [value, setValue] = useState('');
  return (
    <input change={(e) => setValue(e.target.value)} value={value} />
  );
}

 
どこに問題があるのかすぐに分からなくてハマリました。


[参考]

みんなでアジャイル ―変化に対応できる顧客中心組織のつくりかた

みんなでアジャイル ―変化に対応できる顧客中心組織のつくりかた

  • 作者:Matt LeMay
  • 発売日: 2020/03/19
  • メディア: 単行本(ソフトカバー)