新手學習 React 迷惑的點

来源:https://www.cnblogs.com/taoweng/archive/2019/09/04/11461253.html
-Advertisement-
Play Games

網上各種言論說 React 上手比 Vue 難,可能難就難不能深刻理解 JSX,或者對 ES6 的一些特性理解得不夠深刻,導致覺得有些點難以理解,然後說 React 比較難上手,還反人類啥的,所以我打算寫兩篇文章來講新手學習 React 的時候容易迷惑的點寫出來,如果你還以其他的對於學習 React ...


網上各種言論說 React 上手比 Vue 難,可能難就難不能深刻理解 JSX,或者對 ES6 的一些特性理解得不夠深刻,導致覺得有些點難以理解,然後說 React 比較難上手,還反人類啥的,所以我打算寫兩篇文章來講新手學習 React 的時候容易迷惑的點寫出來,如果你還以其他的對於學習 React 很迷惑的點,可以在留言區里給我留言。

為什麼要引入 React

在寫 React 的時候,你可能會寫類似這樣的代碼:

import React from 'react'

function A() {
  // ...other code
  return <h1>前端桃園</h1>
}

你肯定疑惑過,下麵的代碼都沒有用到 React,為什麼要引入 React 呢?

如果你把 import React from ‘react’ 刪掉,還會報下麵這樣的錯誤:

7F6E506E-3025-401D-A492-3B501F8081C6

那麼究竟是哪裡用到了這個 React,導致我們引入 React 會報錯呢,不懂這個原因,那麼就是 JSX 沒有搞得太明白。

你可以講上面的代碼(忽略導入語句)放到線上 babel 里進行轉化一下,發現 babel 會把上面的代碼轉化成:

function A() {
  // ...other code
  return React.createElement("h1", null, "前端桃園");
}

因為從本質上講,JSX 只是為 React.createElement(component, props, ...children) 函數提供的語法糖。

為什麼要用 className 而不用 class

  1. React 一開始的理念是想與瀏覽器的 DOM API 保持一直而不是 HTML,因為 JSX 是 JS 的擴展,而不是用來代替 HTML 的,這樣會和元素的創建更為接近。在元素上設置 class 需要使用 className 這個 API:

    const element = document.createElement("div")
    element.className = "hello" 
  2. 瀏覽器問題,ES5 之前,在對象中不能使用保留字。以下代碼在 IE8 中將會拋出錯誤:

    const element = {
      attributes: {
        class: "hello"
      }
    } 
  3. 解構問題,當你在解構屬性的時候,如果分配一個 class 變數會出問題:

    const { class } = { class: 'foo' } // Uncaught SyntaxError: Unexpected token }
    const { className } = { className: 'foo' } 
    const { class: className } = { class: 'foo' } 

其他討論可見:有趣的話題,為什麼jsx用className而不是class

為什麼屬性要用小駝峰

因為 JSX 語法上更接近 JavaScript 而不是 HTML,所以 React DOM 使用 camelCase(小駝峰命名)來定義屬性的名稱,而不使用 HTML 屬性名稱的命名約定。

來自 JSX 簡介

為什麼 constructor 里要調用 super 和傳遞 props

這是官網的一段代碼,具體見:狀態(State) 和 生命周期

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

而且有這麼一段話,不僅讓我們調用 super 還要把 props 傳遞進去,但是沒有告訴我們為什麼要這麼做。image-20190901222456704

不知道你有沒有疑惑過為什麼要調用 super 和傳遞 props,接下來我們來解開謎題吧。

為什麼要調用 super

其實這不是 React 的限制,這是 JavaScript 的限制,在構造函數里如果要調用 this,那麼提前就要調用 super,在 React 里,我們常常會在構造函數里初始化 state,this.state = xxx ,所以需要調用 super。

為什麼要傳遞 props

你可能以為必須給 super 傳入 props,否則 React.Component 就沒法初始化 this.props

class Component {
  constructor(props) {
    this.props = props;
    // ...
  }
}

不過,如果你不小心漏傳了 props,直接調用了 super(),你仍然可以在 render 和其他方法中訪問 this.props(不信的話可以試試嘛)。

為啥這樣也行?因為React 會在構造函數被調用之後,會把 props 賦值給剛剛創建的實例對象:

const instance = new YourComponent(props);
instance.props = props;

props 不傳也能用,是有原因的。

但這意味著你在使用 React 時,可以用 super() 代替 super(props) 了麽?

那還是不行的,不然官網也不會建議你調用 props 了,雖然 React 會在構造函數運行之後,為 this.props 賦值,但在 super() 調用之後與構造函數結束之前, this.props 仍然是沒法用的。

// Inside React
class Component {
  constructor(props) {
    this.props = props;
    // ...
  }
}

// Inside your code
class Button extends React.Component {
  constructor(props) {
    super(); // 

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Android環境配置 1. 前期準備 Android環境的Eclipse: 網站鏈接: SDK的CPU鏡像資源: 網站鏈接: 為啥要下載這個版本呢?因為我經歷的一晚上的研究,發現Eclipse自帶的AVD不能用(至少我的電腦是這樣) 然後下載對應的SDK: 2. 軟體解壓縮與環境準備 Eclips ...
  • # QzsWanAndroid - [基於 wanandroid.com 開發的 MVP + Retrofit2 + RxJava2 +okhttp3 開發的 Android APP](https://github.com/javaexception/QzsWanAndroid) ![](https ...
  • easyui中formatter的用法 當我們使用easyui需要對某一列進行格式化處理value數據時,可以使用formatter進行格式化 商品類型值為0時,前端將顯示“主體商品”。 商品類型值為1時,前端將顯示“附屬商品”。 value:欄位值 row:行記錄數據 index:行所在索引 js ...
  • 1.不管什麼語言,上來就應該是數據類型了。js也不例外。那麼基本的數據類型我們有,boolean, number, string, null, undefine, symbol, object, function. 2. 有了基本類型,那麼我們怎麼去判斷一個變數的類型尼? 3. 如何去判斷是否是一個 ...
  • Vue 組件系統 vue.js既然是框架,那就不能只是簡單的完成數據模板引擎的任務,它還提供了頁面佈局的功能。本文詳細介紹使用vue.js進行頁面佈局的強大工具,vue.js組件系統。 每一個新技術的誕生,都是為瞭解決特定的問題。組件的出現就是為瞭解決頁面佈局等等一系列問題。vue中的組件分為兩種, ...
  • 用easyui從servlet傳遞json數據到前端頁面的兩種方法 兩種方法獲取的數據在servlet層傳遞的方法相同,下麵為Servlet中代碼,以查詢表中所有信息為例。 通過easyui包含的table標簽中的屬性來獲取後端傳遞的數據 jsp代碼: url:傳遞數據的地址(本篇使用的是servl ...
  • 今天實現網站註銷功能時,需要清除cookie緩存,開始在網上搜索的是“js清除緩存”,發現很多都是預先防患緩存存儲的內容,千篇一律,不過也學習到了;後來換成"js清除cookie"才找到自己想要的結果。 先學習一下預先防治緩存存儲的方式吧 在http中,控制緩存開關的欄位有兩個:Pragma 和 C ...
  • ### es5新增的數組的api + indexOf() 搜索數組中的元素,並返回它所在的位置。 arr.indexOf(str,index) 參數: str為要查找的字元串 index為開始查找的下標 , index可省略 查找字元串a在數組中的位置,返回值為a在數組中第一次出現的位置的下標,如果 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...