[譯]你可以在JSX中使用console.log嗎?

進擊的大蔥發表於2019-03-14

原文連結: 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進行除錯了!

關注我的公眾號,獲取我分享的最新技術推送!

[譯]你可以在JSX中使用console.log嗎?

相關文章