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

2022-08-22 14:07:11 浏览数 (1)

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

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

代码语言:javascript复制
render() {
 return {
  <div>
   <h1>List of todos</h1>
   console.log(this.props.todos)
  </div>
 }
}

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

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

最常用的解决方法

JSX中嵌入JS表达式:

代码语言:javascript复制
render() {
 return (
  <div>
   <h1>List of todos</h1>
   { console.log(this.props.todos) }
  </div>
 );
}

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

将console.log写在return()前面:

代码语言:javascript复制
render() {
 console.log(this.props.todos);
 return (
  <div>
   <h1>List of todos</h1>
  </div>
 );
}

一个炫酷的解决方案

构建一个自定义的组件

代码语言:javascript复制
const ConsoleLog = ({ children }) => {
 console.log(children);
 return false;
};

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

代码语言:javascript复制
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的代码:

代码语言:javascript复制
const element = (
  <h1 className="greeting">
   Hello, world!
  </h1>
);

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

代码语言:javascript复制
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的办法为什么没有用的原因:
代码语言:javascript复制
<div>
 <h1>List of todos</h1>
 console.log(this.props.todos)
</div>

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

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

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

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

代码语言:javascript复制
<div>
 <h1>List of todos</h1>
 { console.log(this.props.todos) }
</div>

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

0 人点赞