Définition d'une propriété "check" dans React

j'ai un problème très gênant avec les cases à cocher. L'application avec laquelle je travaille nécessite une liste de cases à cocher qui représentent les paramètres qui persistent à l'arrière-plan. Il y a une option pour restaurer les paramètres à leur état d'origine.

Au début, j'ai créé un composant qui a un objet comme une carte de paramètres. Chaque paramètre a une clé et une valeur booléenne. Par conséquent:

{
    bubbles: true,
    gregory: false
}

doit être représenté comme:

<input type="checkbox" value="bubbles" checked="checked" />
<input type="checkbox" value="gregory" />

Or, il semble que React ignore comment une case à cocher est censée fonctionner. Je ne veux pas mettre les valeurs des cases à cocher, Je veux la propriété "vérifié".

pourtant, si j'essaie quelque chose comme ça:

<input
    type="checkbox"
    value={setting}
    checked={this.settings[setting]}
    onChange={this.onChangeAction.bind(this)}
/>

je reçois cet avertissement:

avertissement: AwesomeComponent est en train de changer une entrée non contrôlée d'une case à cocher de type à contrôler. Les éléments d'entrée ne doivent pas passer d'un mode non contrôlé à un mode contrôlé (ou vice versa). Décider entre l'utilisation contrôlée ou non l'élément d'entrée pour la durée de vie du composant. Plus d'infos: [inutile docs page j'ai lu plusieurs fois en vain]

alors j'ai décidé de créer un autre composant pour envelopper chaque case à cocher et j'ai eu ceci:

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

checked est une propriété présente directement dans mon état.

cela donne le même avertissement, donc j'ai essayé d'utiliser defaultChecked:

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

ce qui fait disparaître l'avertissement, mais maintenant il est incapable de réinitialiser le checked la valeur par défaut. J'ai donc essayé de jouer avec la méthode componentWillReceiveProps, de cette façon, je suis sûr que mon état est correct, this.state.checked est correct et le composant renvoie à nouveau.

et c'est le cas. Mais la case reste comme elle était à l'origine. Pour l'instant, j'ai laissé cet avertissement Moche et j'utilise checked. Comment puis-je réparer cette chose pour que l'avertissement disparaisse?

je suis penser qu'il y a peut-être un moyen de forcer-rendre le composant, donc il capture le nouveau defaultChecked valeur et l'utilise. Mais je ne sais pas comment faire. Peut-être supprimer l'avertissement pour cette composante? Est-ce possible? Peut-être il y a autre chose qui peut être fait?

16
demandé sur Apollo 2016-08-24 12:54:44

4 réponses

Le problème se pose si vous définissez checked propriété de votre case null ou undefined.

Ceux qui sont un "faussement" valeurs en JS, cependant React traite une valeur de null comme si la propriété n'a pas été définie pas du tout. Depuis l'état par défaut de la case à cocher est désactivée, tout fonctionnera correctement. Ensuite, si vous réglez l'option checkedtrue React pense que la propriété entre soudainement en existence! C'est quand Réagir chiffres vous avez changé d'incontrôlée de contrôlé, depuis maintenant l'hélice!--0--> existe.

Dans votre exemple, vous pouvez vous débarrasser de cet avertissement en changeant checked={this.settings[setting]}checked={!!this.settings[setting]}. Remarquez le double bang (!!). Ils seront convertir null ou undefinedfalse (et laisser true seul), alors React enregistrera votre checked propriété avec une valeur de false et commencer avec un composant de forme contrôlée.

j'ai eu ce problème aussi, et moi aussi, j'ai lu le docs sur contrôlées-composants plusieurs fois sans résultat, mais j'ai finalement compris, alors j'ai pensé partager. Aussi, depuis version 15.2.0 les entrées normales sont déclenchées pour être contrôlées parvalue, alors que les cases à cocher sont initialisées comme contrôlées par le paramètre checked, indépendamment de leur value propriété, qui a ajouté un peu à la confusion.

37
répondu amoebe 2016-09-26 21:27:40

la réponse D'Amoebe est correcte, mais je pense qu'il y a une solution plus propre que la double banque (!!). Il suffit d'ajouter un des defaultprops propriété avec la valeur falsechecked prop de votre composant Checkbox:

import React from 'react';

const Checkbox = ({checked}) => (
  <div>
      <input type="checkbox" checked={checked} />
  </div>
);

Checkbox.defaultProps = {
  checked: false
};

export default Checkbox;
5
répondu Klofi 2017-01-16 16:28:52

en gros, le defaultChecked signifie que vous ne souhaitez pas contrôler l'entrée – il seulement rendu avec cette valeur et ensuite il n'y a aucun moyen de le contrôler. Aussi,value ne doit pas être utilisé, mais checked à la place, votre deuxième code devrait être correct. Et vous ne devriez pas les utiliser simultanément.

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

Pouvez-vous créer un petit violon avec ce comportement?

1
répondu Bloomca 2016-08-24 10:07:50

vous pouvez affecter vos données à l'état et ensuite utiliser la propriété cochée associée à la case individuelle pour définir l'état comme

{   this.state.data.map(function(item, index) {
      return (

        <input type="checkbox" checked={item.value} onChange={this.handleChange.bind(this, index)}/>

      );
    }.bind(this))
    }

les données D'échantillon dans l'état est comme

data: [{name:'bubbles', value: true}, {name:'gregory', value: false}]

JSFIDDLE

0
répondu Shubham Khatri 2016-08-24 11:53:13