Reactとチェックボックスに関する非常に迷惑な問題があります。私が使用しているアプリケーションには、バックエンドで保持される設定を表すチェックボックスのリストが必要です。 設定を元の状態に復元するオプションがあります。
最初に、設定のマップのようなオブジェクトを持つコンポーネントを作成しました。各設定にはキーとブール値があります。したがって:
{
bubbles: true,
gregory: false
}
次のように表されます:
<input type="checkbox" value="bubbles" checked="checked" />
<input type="checkbox" value="gregory" />
現在、Reactはチェックボックスがどのように機能するかについて無知であるようです。チェックボックスの値を設定したくありません。「checked」プロパティが必要です。
それでも、次のようなものを試してみると:
<input
type="checkbox"
value={setting}
checked={this.settings[setting]}
onChange={this.onChangeAction.bind(this)}
/>
私はこの警告を受け取ります:
警告:AwesomeComponentは、制御対象のタイプチェックボックスの非制御入力を変更しています。入力要素は、非制御から制御(またはその逆)に切り替えないでください。コンポーネントの寿命の間、制御された入力要素と制御されていない入力要素のどちらを使用するかを決定します。詳細:[いくつかの役に立たないドキュメントページを何度も読みましたが利用できません]
そこで、個々のチェックボックスをラップする別のコンポーネントを作成することにしました。
<input
type="checkbox"
checked={this.state.checked}
onChange={this.onChangeAction.bind(this)}
/>
これで、checked
は私の状態で直接存在するプロパティです。
これは同じ警告を生成するので、defaultChecked
を使用してみました:
<input
type="checkbox"
defaultChecked={this.state.checked}
onChange={this.onChangeAction.bind(this)}
/>
これにより警告は消えますが、現在はchecked
値をデフォルト値にリセットできません。それで、メソッドcomponentWillReceiveProps
を試してみました。このようにして、私の状態が正しいこと、this.state.checked
が正しいこと、コンポーネントが再びレンダリングされることを確信しています。
そして、それは。ただし、チェックボックスは元のままです。今のところ、そのthatい警告を残し、checked
を使用しています。警告が消えるようにこの問題を修正するにはどうすればよいですか?
コンポーネントを強制的に再レンダリングする方法があるのではないかと考えていたので、新しいdefaultChecked
値をキャプチャして使用します。しかし、私はそれを行う方法がわかりません。おそらく、このコンポーネントの警告onlyを抑制しますか?それは可能ですか?おそらく他に何かできることがありますか?
チェックボックスのchecked
プロパティをnull
またはundefined
に設定すると、問題が発生します。
これらはJSの「誤った」値ですが、 Reactはnull
の値をプロパティが設定されていないかのように扱います まったく。チェックボックスのデフォルト状態はオフになっているため、すべてが正常に機能します。その後、checked
をtrue
に設定すると、Reactはプロパティが突然存在すると考えます!これは、プロップchecked
が存在するため、Reactが非制御から制御に切り替えたときです。
あなたの例では、checked={this.settings[setting]}
をchecked={!!this.settings[setting]}
に変更することにより、この警告を取り除くことができます。ダブルバング(!!
)に注意してください。 null
またはundefined
をfalse
に変換する(そしてtrue
をそのままにする)ので、Reactはchecked
プロパティをfalse
の値で登録し、制御されたフォームコンポーネントから始めます。
私もこの問題を抱えており、私も 制御コンポーネントに関するドキュメント 役に立たない時間を読みましたが、最終的にそれを見つけたので、共有したいと思いました。また、 バージョン15.2. 通常の入力はvalue
を設定することによって制御されるようにトリガーされるため、チェックボックスはchecked
プロパティに関係なくvalue
を設定することによって制御されるように初期化されます。
Amoebeの答えは正しいですが、ダブルバンク(!!
)よりもクリーンなソリューションがあると思います。 Checkboxコンポーネントのfalse
propに値checked
を持つ defaultProps プロパティを追加するだけです。
import React from 'react';
const Checkbox = ({checked}) => (
<div>
<input type="checkbox" checked={checked} />
</div>
);
Checkbox.defaultProps = {
checked: false
};
export default Checkbox;
基本的に、defaultChecked
は、入力を制御したくないことを意味します。この値でレンダリングするだけなので、制御する方法はありません。また、value
は使用すべきではありませんが、代わりにchecked
を使用する必要があるため、2番目のコードは正しいはずです。また、両方を同時に使用しないでください。
<input
type="checkbox"
checked={this.state.checked}
onChange={this.onChangeAction.bind(this)}
/>
この動作で小さなフィドルを作成できますか?
データを状態に割り当ててから、個々のチェックボックスに関連付けられているチェックされたプロパティを使用して、状態を次のように設定できます。
{ this.state.data.map(function(item, index) {
return (
<input type="checkbox" checked={item.value} onChange={this.handleChange.bind(this, index)}/>
);
}.bind(this))
}
状態のサンプルデータは
data: [{name:'bubbles', value: true}, {name:'gregory', value: false}]