I'm trying to wrap my head around JSX. I've found a very weird behavior. This is my code:
const name = undefined;
const myFunc = () => undefined;
let template = (
<div>
{myFunc()}
{name}
{undefined}
</div>
);
ReactDOM.render(template, document.querySelector("#root"));
The output is one time: undefined
Why is the const "name" the only undefined value that is resolved to a string? What is the difference between this const and the other two expressions? (Same with Boolean and null.) Please see my code here: codepen
I'm trying to wrap my head around JSX. I've found a very weird behavior. This is my code:
const name = undefined;
const myFunc = () => undefined;
let template = (
<div>
{myFunc()}
{name}
{undefined}
</div>
);
ReactDOM.render(template, document.querySelector("#root"));
The output is one time: undefined
Why is the const "name" the only undefined value that is resolved to a string? What is the difference between this const and the other two expressions? (Same with Boolean and null.) Please see my code here: codepen
Share Improve this question edited Apr 28, 2019 at 6:31 Sagiv b.g 31k10 gold badges72 silver badges104 bronze badges asked Oct 20, 2018 at 9:19 Nave HazanNave Hazan 3515 silver badges15 bronze badges 2- 3 Technically nothing should be displayed since all falsy values should be ignored. It seems one of the values gets stringified somehow. – Sulthan Commented Oct 20, 2018 at 9:22
- 2 Cant reproduce in JsFiddle, what React version do you use? – Marcel T. Commented Oct 20, 2018 at 9:49
3 Answers
Reset to default 10That's because JSX
is syntactic sugar for React.createElement(ponent, props, ...children)
It will ignore these types (see DOCS):
- Boolean
- undefined
- null
I just realized that this happens only on some editors like codepen because they run the code in the global context and window.name will always be a string.
window.name will convert all values to their string representations by using the toString method.
If you change the variable to something else, lets say name1
it behaves as expected.
const name1 = undefined;
const myFunc = function(){return undefined};
let template = (
<div>
{name1}
{undefined}
{myFunc()}
</div>
);
By the way, stack-snippets behave the same:
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./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Other Editors like codesandbox
or jsfiddle
will wrap the code in a function, hence there is no conflict with the window.name
.
The output here would be empty between your divs. I put this code into jsfiddle to demonstrate:
const name = undefined;
const myFunc = () => undefined;
let template = (
<div>
{myFunc()}
{name}
{undefined}
Hello world
</div>
);
Notice all you can see is the "Hello world" that I added.
It's because the global variable name
is the property window.name and will always be a string.
window.name
will convert all values to their string representations by using the toString method.
name = undefined
foo = undefined
console.log('`name` is a', typeof name, ', but `foo` is a', typeof foo)
Use a different global variable name, and it should work as expected. But you should typically not use global constants in your templates anyway.