Почему React разрешает undefined / boolean / null в строку только тогда, когда они являются переменными? - PullRequest
0 голосов
/ 20 октября 2018

Я пытаюсь обернуть голову вокруг JSX.Я обнаружил очень странное поведение.Это мой код:

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

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

Вывод один раз : не определено

Почему const "name" является единственным неопределенным значением, которое разрешается в строку?В чем разница между этим const и двумя другими выражениями?(То же самое с логическим и нулевым.) Пожалуйста, посмотрите мой код здесь: codepen

Ответы [ 3 ]

0 голосов
/ 20 октября 2018

Это потому, что JSX является синтаксическим сахаром для React.createElement(component, props, ...children)
Он будет игнорировать эти типы (см. DOCS ):

  • Boolean
  • undefined
  • null

Я только что понял, что это происходит только в некоторых редакторах, таких как codepen, потому что они запускают код в глобальном контексте и в окне .имя всегда будет строкой .

window.name преобразует все значения в их строковые представления с помощью метода toString.

Если вы измените переменную на что-то другое, скажем, name1 itведет себя как ожидалось.

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

Кстати, фрагменты стека ведут себя одинаково:

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>

Другие редакторы, такие как codesandbox или jsfiddle, будут переносить код в функцию, следовательно, нет конфликта с window.name.

0 голосов
/ 20 октября 2018

Это потому, что глобальная переменная name является свойством window.name и всегда будет строкой.

window.name преобразует все значения в свои строковые представленияиспользуя метод toString.

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

Используйте другое имя глобальной переменной, и оно должно работать как положено.Но вы все равно не должны использовать глобальные константы в своих шаблонах.

0 голосов
/ 20 октября 2018

Вывод здесь будет пустым между вашими div.Я поместил этот код в jsfiddle , чтобы продемонстрировать:

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

Обратите внимание, что вы видите только «Hello world», который я добавил.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...