Reactのuncontrolled input warningで困った時に確認するべきたった1つのこと

たまに見るuncontrolled input関連の警告についての小ネタです。
知っていると原因がすぐわかるのですが、知らないと結構デバックに時間が掛かる面倒な警告です。

まず、ReactのForm関連コンポーネントの考え方にはcontrolleduncontrolledの2つがあります。

簡単に両者の違いを説明すると、値がReactのstateで管理されているかどうかです。

controlledの方は、値がReactのstateで管理されていて、setStateしないと変更できません。
それに対してuncontrolledは、値がReactのstateで管理されていないので、従来の方法で値を変更できるのですが、lifecycleイベントなどのReactの様々な恩恵を受けにくくなります。

で、本題ですが。

Reactでフォームがある画面を開発していると、ちょくちょくお目に掛かるのが次の警告です。
特にフォーム部品をcontrolledにしているにも関わらず、何かのタイミングでこの警告が発生するケースがあります。

1
Warning: App is changing a controlled input of type checkbox to be uncontrolled.
Input elements should not switch from controlled to uncontrolled (or vice versa).
Decide between using a controlled or uncontrolled input element for the lifetime of the component.
More info: https://fb.me/react-controlled-components

内容としては、フォーム部品の状態が何かの原因でcontrolledからuncontrolledになったことを警告している内容です。

しかし、この「何か」が結構わからなかったりします。

どこをチェックすればいいのか?

これはReactのフォームコンポーネントに割り当てられているStateの値が、nullundefinedになってしまうタイミングがあるためです。

フォームコンポーネントはStateの値がnullundefinedになった場合、uncontrolledになります。

この警告が発生する状況は大きく2つです。
もしこの警告が出た場合は、これらをチェックしてみるのが解決の近道です。

Stateの初期値

まず1つ目はフォーム部品のStateの初期値にnullundefinedが設定されてる場合です。

1
this.state = {
  value: undefined
};

もちろんプロパティ自体が宣言されていない場合も同様にundefinedとなるので注意が必要です。

1
// this.state.valueはundefined
this.state = {};

setState

もう1つはsetStateで値がnullundefinedになるケースです。

1
this.setState({
  value: undefined
});

オブジェクトをそのまま設定する場合など、うっかりして起きやすいと思います。

まとめ

Reactのフォームコンポーネントは、割り当てられているStateの値がnullundefinedになると、uncontrolledになってしまうので注意するべしという話でした。