As a coding instructor, I have seen many students trying this:
render() {
return (
<div>
<h1>List of todos</h1>
console.log(this.props.todos)
</div>
);
}
This will not print the expected list in the console. It will just render the string console.log(this.props.todos) in the browser.
Let's first take a look at some solutions which are very straightforward, then we will explain the reason.
The most used solution:
Embed the expression in your JSX:
render() {
return (
<div>
<h1>List of todos</h1>
{ console.log(this.props.todos) }
</div>
);
}
Another popular solution:
Place your console.log
before the return()
:
render() {
console.log(this.props.todos);
return (
<div>
<h1>List of todos</h1>
</div>
);
}
A fancy solution:
Get fancy by writing and using your own <ConsoleLog>
Component:
const ConsoleLog = ({ children }) => {
console.log(children);
return false;
};
Then use it:
render() {
return (
<div>
<h1>List of todos</h1>
<ConsoleLog>{ this.props.todos }</ConsoleLog>
</div>
);
}
Why is that so?
We have to remember that JSX is not vanilla JavaScript, nor is it HTML. It is a syntax extension.
Ultimately, JSX gets compiled into vanilla JavaScript.
For example, if we write the following JSX:
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
It will get compiled down to:
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
Let's review the parameters of React.createElement
:
-
'h1'
: This is the name of the tag, as a string -
{ className: 'greeting' }
: These are the props used in<h1>
. It is converted to an object. The key of the object is the name of the prop and the value, its value. -
'Hello, world!'
: This is called the children. It's whatever is passed between the opening tag<h1>
and the closing tag</h1>
.
Let's now review the failing console.log that we tried to write at the start of this article:
<div>
<h1>List of todos</h1>
console.log(this.props.todos)
</div>
This would get compiled down to:
// when more than 1 thing is passed in, it is converted to an array
React.createElement(
'div',
{}, // no props are passed/
[
React.createElement(
'h1',
{}, // no props here either
'List of todos',
),
'console.log(this.props.todos)'
]
);
See how the console.log
is passed as a string to createElement
. It is not executed.
It makes sense, above we have the title List of todos
. How could the computer know which text needs to be executed and which is something you want to render?
Answer: It considers both as a string. It ALWAYS considers the text as a string.
Hence, if you want that to be executed, you need to specify to JSX to do so. By embedding it as an expression with {}
.
And there you go! Now you know where, when and how console.log
can be used inside of JSX!