[译]你可以在JSX中使用console.log吗?

3,104 阅读3分钟

原文链接: Can you console.log in JSX?
原文作者: Llorenç Muntaner
译者: 进击的大葱
推荐理由: 很多React初学者不知如何在React的JSX中使用console.log进行调试,本文将会介绍几个在JSX中使用console.log的方法。

作为一个编程老师,我经常看到学生写以下代码进行调试:

render() {
    return {
        <div>
            <h1>List of todos</h1>
            console.log(this.props.todos)
        </div>
    }
}

可是上面的代码并不可以得到他们想要的结果,浏览器会把这段代码 console.log(this.props.todos) 当做纯文本在界面展示出来 。

先不急着解释这个为什么不行的原因,让我们先看几个在JSX中正确使用console.log的方法。

最常用的解决方法

JSX中嵌入JS表达式:

render() {
  return (
    <div>
      <h1>List of todos</h1>
      { console.log(this.props.todos) }
    </div>
  );
}

另外一个比较流行的解决方案

console.log写在return()前面:

render() {
  console.log(this.props.todos);
  return (
    <div>
      <h1>List of todos</h1>
    </div>
  );
}

一个炫酷的解决方案

构建一个自定义的<ConsoleLog>组件

const ConsoleLog = ({ children }) => {
  console.log(children);
  return false;
};

然后在需要的地方使用这个组件:

render() {
  return (
    <div>
      <h1>List of todos</h1>
      <ConsoleLog>{ this.props.todos }</ConsoleLog>
    </div>
  );
}

这个方法有用的原因是, 布尔值false不会被渲染出来。

为什么第一个方法不可以呢?

我们必须要记住JSX既不是原生的JavaScript语法,也不是HTML语法。它只是一个语法扩展。你写的JSX都会被诸如babel-plugin-transform-react-jsx的工具转换为原生JS代码。

举个例子,假如我们写了以下JSX的代码:

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);

经过编译工具的转换后,它将会变成以下这个样子:

const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);

我们再看一下React.createElement这个方法接收的参数分别是什么:

  • h1: 第一个参数是你要渲染的HTML元素的名称, 它是一个字符串。
  • {className: 'greeting'}: 第二个参数是一个对象, 这个对象是你传入h1这个元素的属性。这个对象的key是属性的名称,key对应的值是你在JSX中为这个key赋予的值。
  • Hello, world!: 第三个参数是h1这个元素的子元素children。它的值是包在开始标签<h1>和关闭标签</h1>之间的所有内容。

明白React.createElement这个函数各个参数的意义后,我们再回头看一下文章一开始介绍的那种直接在JSX里面写console.log的办法为什么没有用的原因:

<div>
  <h1>List of todos</h1>
  console.log(this.props.todos)
</div>

以上的代码编译成原生JS后会变成:

// 如果一个标签内的子元素超过一个,它们会被整合成一个数组传入函数
React.createElement(
  'div',
  {}, // 外面没有传入参数
  [ 
    React.createElement(
      'h1',
      {}, // 这里也没有参数
      'List of todos',
    ),
    'console.log(this.props.todos)'
  ]
);

由上可知,console.log(this.props.todos)这个代码被当成了字符串传入了React.createElement中。这就是为什么这段代码没有被执行的原因。

如果你希望你的代码被执行,你需要使用{}告诉JSX你输入的字符串是可以被执行的代码,也就是:

<div>
  <h1>List of todos</h1>
  { console.log(this.props.todos) }
</div>

看完这边文章,我想你应该知道如何在JSX中使用console.log进行调试了!

关注我的公众号,获取我分享的最新技术推送!