1
votes

Réagir vérifier si la propriété existe ET est faux

J'ai quelques entrées de formulaire et j'aimerais pouvoir en définir certaines comme obligatoires et d'autres facultatives. Je voudrais utiliser la propriété required pour que le HTML soit sémantiquement correct:

handleBlur = (e) => {
  if (e.target.value === '') {
    // show an error if field empty and required
    // NOT explicitly set to false
    if (!this.props.required) {
      setError('This field is required') 
    }
  }
}

Je préférerais ajouter required = {false} donc je n'ai pas à ajouter l'accessoire requis à chaque champ. Cependant, vérifier cela devient alors quelque peu étrange:

<input onBlur={this.handleBlur} name="first_field" />
<input onBlur={this.handleBlur} name="first_field" required={false} />
<input onBlur={this.handleBlur} name="first_field" />

Je ne peux pas faire if (! This.props.required) car ce serait true si la propriété n'est pas déclarée.

Y a-t-il un moyen plus simple de gérer cela que la double vérification?

MISE À JOUR: J'ai supposé à la hâte que c'était un problème de code, mais après quelques discussions dans les commentaires ci-dessous, je pense maintenant que c'est un problème sémantique de savoir comment l'attribut HTML 'required' doit être utilisé, OU comment gérer cela avec React. J'ai choisi de ne pas supprimer la question car cela pourrait avoir une certaine valeur pour d'autres à l'avenir.


10 commentaires

Veuillez publier un exemple reproductible minimal . En particulier, vous devez montrer un composant simple qui illustre le concept sur lequel vous vous interrogez.


Toutes mes excuses, j'ai un peu étoffé l'exemple.


Nous vous remercions de l'information supplémentaire. Comment la fonction handleBlur est-elle liée aux éléments input au-dessus?


J'ai omis le gestionnaire d'événements pour garder les entrées concises. Je les ai rajoutés.


Voir ma réponse modifiée. En bref, votre accessoire doit être nommé optional au lieu de required .


De plus, il semble que vous essayez d'éviter de définir required sur chacun des éléments input enfants alors qu'ils sont en fait requis. Comme je le dis dans ma réponse, vous ne devriez pas essayer de faire cela.


@ Code-Apprentice Je pense que vous avez raison, et je pense que c'est le problème racine, pas la question de code d'origine - je ne sais pas comment gérer les réponses / commentaires d'une manière qui fonctionne bien pour le débordement de pile. Les pensées?


Vous avez reçu plusieurs réponses ainsi que des modifications au fur et à mesure que votre question était plus claire. Faites voter celles que vous trouvez utiles et acceptez-en une si elle résout réellement le problème.


Il semble que la question fondamentale que vous vous posez est de savoir comment modifier la signification de l'attribut required sur un élément input . La réponse est: Vous ne pouvez pas le faire. Au lieu de cela, vous devriez écrire votre propre composant OptionalInput qui a un accessoire nommé optional et rend Ensuite, vous pouvez utiliser ce composant où vous le souhaitez, comme vous le demandez ici.


Oui, je pense que vous ne devriez pas mettre d'accessoires personnalisés sur les éléments DOM: reactjs.org/warnings/unknown- prop.html


3 Réponses :


0
votes

La façon la plus simple d'aborder cela serait d'utiliser un cast booléen forcé. Toutes les valeurs fausses telles que undefined, null, 0 ou false aboutiront à false, toute autre valeur sera considérée comme vraie. Dans ce cas, comme required n'existe pas tant qu'il n'est pas spécifié comme accessoire, il retournera false jusqu'à ce que sa valeur lui soit attribuée. Vous pouvez essayer ce qui suit sur le terminal de votre navigateur:

const data = {};
console.log('no required has been defined, ', !!data.required);
data.required = false;
console.log('required has been set to false, ', !!data.required);
data.required = true;
console.log('required should be true now, ', !!data.required);
delete data.required;
console.log('back to not defined, ' !!data.required);

J'espère que cela vous aidera!


0 commentaires

3
votes

Il semble que vous essayez de changer la sémantique de required . Cet attribut doit être défini par défaut sur false s'il n'est pas présent. La définition explicite de required = {false} est parfaitement bien. Cependant, changer la signification lorsque required n'est pas présent me semble être une mauvaise pratique.

Au lieu de cela, vous pouvez écrire votre propre composant. Vous pouvez le nommer OptionalInput par exemple. Donnez-lui un accessoire nommé facultatif , puis une fonction render () avec quelque chose comme ceci:

render() {
    return <input name={this.props.name}
                  id={this.props.id}
                  ...
                  required={!this.props.optional}/>
}

Vous allez doivent également ajouter des accessoires pour tous les attributs input que vous souhaitez prendre en charge.


3 commentaires

Cela peut être vrai - j'ai envisagé de passer à optional = {true} à la place, mais maintenant j'ajoute un nouvel accessoire à l'entrée HTML au lieu d'utiliser l'attribut existant. Je pourrais définir required sur true dans tous les cas, sauf lorsqu'il est explicitement défini sur false.


@Toby Vous pouvez facilement ajouter un accessoire facultatif à votre propre composant. Ensuite, vous devrez ajouter required = {! Optional} à tous les éléments input enfants.


cela ne devrait-il pas être ! this.props.optional dans votre extrait de code?



3
votes

Vous pouvez le simplifier en utilisant defaultProps:

 <input name="first_field" optional />

Si la propriété n'est pas définie, true sera utilisé à la place. p>

Cependant, il peut être préférable d'inverser la condition et de l'appeler facultatif , vous pourrez alors l'utiliser simplement comme:

defaultProps: {
   required: true
}


3 commentaires

J'ai pensé à cela - mais il semble sémantiquement incorrect d'ajouter un attribut plutôt que d'utiliser l'attribut HTML existant. Je n'avais pas pensé à utiliser propTypes pour cela, je me penche là-dessus maintenant.


@Toby React n'est pas du HTML. Avoir required = {true} par défaut est un peu inattendu pour les utilisateurs de votre composant précisément parce qu'il se comporte différemment qu'en HTML.


L'ajout de facultatif à un élément d'entrée ne fera rien car input ne reconnaît pas cet attribut.