web-dev-qa-db-fra.com

Pourquoi React ne résout-il pas indéfini/boolean/null en chaîne que lorsqu'il s'agit de variables?

J'essaie de comprendre JSX . J'ai trouvé un comportement très étrange . C'est mon code:

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

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

La sortie est une fois: Undefined

Pourquoi le const "nom" est-il la seule valeur non définie résolue en une chaîne? Quelle est la différence entre ce const et les deux autres expressions? (Idem avec Boolean et null.) Veuillez vous reporter à mon code ici: codepen

9
Nave Hazan

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

  • Booléen
  • undefined
  • nul

Je viens de me rendre compte que cela ne se produit que sur certains éditeurs, tels que codepen, car ils exécutent le code dans le contexte global et window.name sera toujours une chaîne

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

Si vous remplacez la variable par autre chose, disons name1, il se comporte comme prévu. 

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

À propos, les extraits de pile 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 tels que codesandbox ou jsfiddle encapsuleront le code dans une fonction. Il n'y a donc pas de conflit avec le window.name.

7
Sagiv b.g

La sortie ici serait vide entre vos divs. Je mets ce code dans jsfiddle pour démontrer:

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

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

0
Yoni Weisbrod

C'est parce que la variable globale name est la propriété window.name et sera toujours une chaîne.

window.name convertira toutes les valeurs en leurs représentations 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 il devrait fonctionner comme prévu. Cependant, vous ne devez généralement pas utiliser de constantes globales dans vos modèles.

0
Håken Lid