10 votes

Pourquoi React résout-il undefined/boolean/null en string uniquement lorsqu'il s'agit de variables ?

J'essaie de me faire une idée de JSX. J'ai trouvé un comportement très bizarre. Voici mon code :

const name = undefined;
const myFunc = () => undefined;
let template = (
  <div>
    {myFunc()}
    {name}
    {undefined}
  </div>
);

ReactDOM.render(template, document.querySelector("#root"));

Le résultat est une fois : indéfini

Pourquoi la constante "name" est-elle la seule valeur indéfinie qui est résolue en une chaîne de caractères ? Quelle est la différence entre cette const et les deux autres expressions ? (Même chose pour Boolean et null). Veuillez voir mon code ici : codepen

8voto

Sagiv b.g Points 15448

C'est parce que JSX est un sucre syntaxique pour React.createElement(component, props, ...children)
Il ignorera ces types (voir DOCS ):

  • Booléen
  • indéfini
  • null

Je viens de réaliser que cela n'arrive que sur certains éditeurs comme codepen car ils exécutent le code dans le contexte global et window.name sera toujours une chaîne de caractères .

window.name convertira toutes les valeurs en leur représentation sous forme de chaîne en utilisant la méthode toString.

Si vous changez la variable en quelque chose d'autre, par exemple name1 il se comporte comme prévu.

const name1 = undefined;
const myFunc = function(){return undefined};
let template = (
  <div>
    {name1}
    {undefined}
    {myFunc()}
  </div>
);

D'ailleurs, les stack-snippets se comportent de la même manière :

console.log('name is ', name);
const name = undefined;
console.log('and now name is ', name);
const name1 = undefined;
const myFunc = function(){return undefined};
let template = (
  <div>
    {name}
    {name1}
    {undefined}
    {myFunc()}
  </div>
);

ReactDOM.render(template, document.querySelector("#root"));

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

D'autres éditeurs comme codesandbox o jsfiddle enveloppera le code dans une fonction, il n'y a donc pas de conflit avec l'option window.name .

0voto

Yoni Weisbrod Points 57

Le résultat ici serait vide entre vos divs. J'ai mis ce code dans jsfiddle à démontrer :

const name = undefined;
const myFunc = () => undefined;
let template = (
  <div>
    {myFunc()}
    {name}
    {undefined}
    Hello world
  </div>
);

Remarquez que tout ce que vous pouvez voir est le "Hello world" que j'ai ajouté.

0voto

Håken Lid Points 10106

C'est parce que la variable globale name est la propriété nom de la fenêtre et sera toujours une chaîne de caractères.

window.name convertira toutes les valeurs en leur représentation sous forme de chaîne en utilisant la méthode toString.

name = undefined
foo = undefined
console.log('`name` is a', typeof name, ', but `foo` is a', typeof foo)

Utilisez un nom de variable globale différent, et cela devrait fonctionner comme prévu. Mais vous ne devriez généralement pas utiliser de constantes globales dans vos modèles de toute façon.

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