99 votes

Violation d'invariant : Les chaînes de texte doivent être rendues dans un composant <Text>.

J'ai fait la mise à jour de la RN 0.54 à 0.57 et mon application s'est pratiquement effondrée à cause de l'utilisation des éléments React Native.

J'ai utilisé leur fonctionnalité d'erreur sur TextInput qui permettent essentiellement d'activer des accessoires permettant de styliser le message d'erreur et de définir votre message d'erreur. Très pratique, mais la mise à jour a cassé ces composants et je suis maintenant accueilli par cette erreur :

Invariant Violation: Text strings must be rendered within a <Text> Component.

J'ai donc supprimé ce code et l'erreur disparaît, mais le problème persiste lorsque j'exécute ce code :

{ this.state.event.cards[i].fields[j].error && 

  <Text style={{ color: '#e74c3c', fontSize: 14, paddingLeft: 5 }}>
    {this.state.event.cards[i].fields[j].error}
  </Text>
}

Lorsque je commence à taper dans un champ de saisie de texte, le message d'erreur prend la forme d'une chaîne vide. Ainsi, si une erreur est renvoyée, le fait de taper dans le champ fera disparaître l'erreur.

Dès que this.state.event.cards[i].fields[j].error devient une chaîne de caractères, je reçois cette erreur. Cependant, vous pouvez voir que je vérifie si l'erreur existe, puis j'affiche simplement l'erreur, ou du moins j'essaie.

Une autre paire d'yeux serait reconnaissante sur ce point.

0 votes

Assurez-vous que votre JSX est exempt d'erreurs et que vous n'avez pas ajouté accidentellement du texte inattendu.

130voto

BeQI Points 168

Je me suis tiré une balle dans le pied trop souvent avec ça, alors je laisse ça ici pour que la prochaine personne ne...

Chaque fois que vous voyez

Invariant Violation: Text strings must be rendered within a <Text> component

99% des cas sont dus à l'utilisation d'un rendu conditionnel avec seulement && au lieu d'instructions ternaires ? :. Pourquoi ? Parce que lorsque votre condition se résout en indéfini il n'y a pas de composants à cet endroit, contrairement à null ou à un tableau vide qui aurait montré en toute sécurité un espace vide et vous aurait sauvé de l'écran rouge de l'enfer.

Changez TOUTES VOS RENDUS CONDITIONNELS LOGIQUES en rendus ternaires.

ie :

NE PAS FAIRE

widgetNumber === 10 && <MyComponent />

DO DO

widgetNumber === 10 ? <MyComponent /> : null

Chaque fois. S'il te plaît. Pour l'amour de la réaction native.

2 votes

La meilleure réponse ! Cette approche avec l'utilisation de l'opérateur ternaire me semble être une idée bien plus solide que de recourir à ceci !!this.state.error &&

0 votes

Merci @MarkColling

2 votes

En effet, le meilleur. Un sauveur de vie !

64voto

Tare Gaskin Points 66

Cela se produit également lorsque vous avez des /* Commentaires */ dans votre fonction return().

0 votes

D'accord, j'ai passé 3 jours de débogage à cause d'un commentaire dans une fonction de rendu.

0 votes

Moi aussi, j'ai passé une journée à déboguer et c'était une ligne commentée dans ma fonction de rendu.

1 votes

@Tare. belle prise. Merci

64voto

Yuci Points 3538

Pour moi, le code suivant fonctionne bien, à condition que this.state.error === undefined ou ce n'est pas une chaîne vide.

render() {
  return (
    <View>
      {this.state.error &&

        <Text>
          Error message: {this.state.error}
        </Text>
      }
    </View>
  );
}

Si l'état d'erreur est changé en chaîne vide '', vous aurez l'exception susmentionnée : Invariant Violation: Text strings must be rendered within a <Text> component

La raison en est que, lorsque this.state.error === '' l'expression suivante sera évaluée comme une chaîne vide, c'est-à-dire '', et cela provoquera Invariant Violation: Text strings must be rendered within a <Text> component

{this.state.error &&

  <Text>
    Error message: {this.state.error}
  </Text>
}

Lorsque this.state.error === undefined l'expression sera évaluée comme undefined c'est ce que nous attendons, et c'est bien.

2 votes

C'est une très bonne explication, je vous en remercie. Je suis heureux de la marquer comme correcte.

0 votes

Vous pouvez aussi l'écrire comme ceci : {Object.keys(this.state.error).length>0 && <Texte> Message d'erreur : {this.state.error} </Text> } }

36voto

Otani Shuzo Points 118

J'utiliserais !! que j'appelle opérateur bang bang pour boolianiser error . Cela devrait fonctionner.

{!!this.state.error && (
  <Text>
    Error message: {this.state.error}
  </Text>
)}

Si error est une chaîne de caractères, quel que soit votre texte, il doit être entouré de <Text /> comme le dit le message d'erreur dans React Native, qui est différent du web.

3 votes

Sur react 59.9, cela a corrigé l'erreur pour moi. Il s'avère que la valeur était une chaîne vide. Bizarrement, l'erreur ne s'est produite que sur Android.

6voto

Lucas Falcão Points 61

J'ai eu le même problème et le commentaire de @serdasenay m'a fait comprendre la cause profonde.

En utilisant la syntaxe {condition && <Element/>} n'est pas mauvais en soi, mais il est important de savoir ce qui se passe.

La racine du problème est le court-circuitage de la logique. En Javascript, les expressions logiques s'évaluent, et && évalue le dernier true valeur équivalente. Mais pas à true mais à la valeur réelle avant qu'elle ne soit convertie en booléen. C'est ce qui permet cette syntaxe pour commencer. Depuis <Element/> est toujours true si condition est true l'expression est évaluée à <Element/>

Le problème se pose lorsque la condition est false . Lorsqu'un && échoue, elle est évaluée à la première valeur, à savoir condition . Mais avant d'être transformé en booléen. Ainsi, si vous utilisez une chaîne de caractères directe ou un nombre en tant que condition et il est évalué à false l'expression logique sera évaluée à cette chaîne ou ce nombre. Ex : {array.length && <List/>} avec un tableau vide est évalué à {0} ce qui entraîne l'erreur.

La solution consiste à s'assurer condition est une vraie valeur booléenne (et cela fonctionne parce que React peut gérer le rendu des booléens - on pense que React les ignore simplement). Faites donc ce qui suit : {array.length > 0 && <List/>}

0 votes

Merci ! Cela s'est avéré être le cas pour moi aussi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X