web-dev-qa-db-ja.com

Reactにチェックボックス「check」プロパティを設定します

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を抑制しますか?それは可能ですか?おそらく他に何かできることがありますか?

28
Apollo

チェックボックスのcheckedプロパティをnullまたはundefinedに設定すると、問題が発生します。

これらはJSの「誤った」値ですが、 Reactはnullの値をプロパティが設定されていないかのように扱います まったく。チェックボックスのデフォルト状態はオフになっているため、すべてが正常に機能します。その後、checkedtrueに設定すると、Reactはプロパティが突然存在すると考えます!これは、プロップcheckedが存在するため、Reactが非制御から制御に切り替えたときです。

あなたの例では、checked={this.settings[setting]}checked={!!this.settings[setting]}に変更することにより、この警告を取り除くことができます。ダブルバング(!!)に注意してください。 nullまたはundefinedfalseに変換する(そしてtrueをそのままにする)ので、Reactはcheckedプロパティをfalseの値で登録し、制御されたフォームコンポーネントから始めます。

私もこの問題を抱えており、私も 制御コンポーネントに関するドキュメント 役に立たない時間を読みましたが、最終的にそれを見つけたので、共有したいと思いました。また、 バージョン15.2. 通常の入力はvalueを設定することによって制御されるようにトリガーされるため、チェックボックスはcheckedプロパティに関係なくvalueを設定することによって制御されるように初期化されます。

55
amoebe

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;
7
Klofi

基本的に、defaultCheckedは、入力を制御したくないことを意味します。この値でレンダリングするだけなので、制御する方法はありません。また、valueは使用すべきではありませんが、代わりにcheckedを使用する必要があるため、2番目のコードは正しいはずです。また、両方を同時に使用しないでください。

<input
    type="checkbox"
    checked={this.state.checked}
    onChange={this.onChangeAction.bind(this)}
/>

この動作で小さなフィドルを作成できますか?

1
Bloomca

データを状態に割り当ててから、個々のチェックボックスに関連付けられているチェックされたプロパティを使用して、状態を次のように設定できます。

{   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}]

JSFIDDLE

0
Shubham Khatri