circuit

Can you console.log in JSX?

TLDR: Embed the expression




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!




Continue Learning