從零開始的react入門教程(一),讓我們從hello world開始


壹 ❀ 引

按照之前的計划,從這個月開始,我將由淺至深更新一些react相關的技術博文。由於我目前也是react新手一名,所以文章本質上也算自己學習歷程的記錄,倘若這些文章能幫助到一些人那就再好不過了。那么這一篇文章就作為一個新的開端,從零開始一起變得更強吧,本文開始。

貳 ❀ 准備工作

在學習基礎知識之前,我們可以在本地搭建並運行一個react應用,便於后續學習時例子效果預覽。請先確保電腦已成功安裝node.js

比如我的學習項目都喜歡丟在D盤,所以可以在D盤新建一個job文件夾(名字隨你喜歡),進入job目錄,打開終端,這里我用的git終端。執行復制npx create-react-app my-app命令並回車,等待安裝完成。

等到出現Happy hacking!,說明下載完成。

之后就可以看到job目錄下多了一個my-app文件夾,這就是我們下載的react應用了。雙擊進入my-app目錄,再進入src文件夾,刪除所有文件之后,創建index.css與index.js文件,像這樣:

用編輯器(我用的vscode)打開my-app項目,在前面創建的index.js中拷貝如下代碼:

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";

ReactDOM.render(<h1>Hello, world!</h1>, document.getElementById("root"));

注意,由於react的jsx語法特性,我們可以在js中編寫html,所以習慣格式化代碼的同學可能會將代碼格式出問題,畢竟js中無法識別HTML。對於這個問題我們可以通過切換編輯器語言模式來解決,點擊編輯器右下角的語言,如下圖:

輸入java可以看到下方有個javaScript React,選擇此語言,再格式化你就發現支持jsx語法了。

每次點擊右下角切換語言也比較麻煩,好的做法是給選擇語言模式直接配置一個鍵盤快捷方式。點擊編輯器左上角的文件--->首選項--->鍵盤快捷方式,之后輸入語言,可以看到有一個更改語言模式。點擊左邊的修改圖標,輸入你想要的快捷方式,保存即可,這里我用快捷鍵是ctrl+k,之后就可以通過快捷鍵快速切換語言模式了。

ok,簡單說了下語言模式的事情,現在我們可以通過ctrl+~打開編輯器的終端,然后輸入npm start並回車。

你會發現瀏覽器自動打開了一個頁面,這就是我們本地開發環境成功跑起來了。使用本地環境的好處是,我們每次修改並保存代碼,頁面都會自動刷新,而此時頁面赫然顯示了一句 Hello, world!,恭喜你,到這里我們成功創建了第一個屬於自己的應用,雖然它目前還很簡單,但通過后面的學習,我們來一起讓它變得更酷!

叄 ❀ jsx基礎

按照以往傳統的開發習慣,dom結構我們一般寫在html中,而js文件會負責業務相關邏輯,但站在react的角度,我們會在js中編寫html相關代碼,如果你有了解vue的jsx語法,我想你會更快接受這一設定,之前沒了解也不用擔心,我們來解釋下文章開頭代碼做了什么。

讓我們打開項目的public文件,查看index.html,可以看到代碼中有一個id為root的div盒子,結合我們前面例子中ReactDOM.render編譯的內容,其實不難理解,render只是將需要編譯的dom,塞到了root的盒子中,這種指定應用容器以及編譯內容的思想其實與vue以及angularjs是相似的,只是現在html換了個地方編寫而已。

jsx屬於JavaScript的語法拓展,事實上它既不是標簽語法,也不是普通字符串(官方稱呼react元素),但它具備JavaScript全部功能。我們編寫的jsx其實會被bable轉譯成React.createElement()調用(vue也有類似的createElement方法),比如下面這段代碼是等效的:

const ele = <h1 className="echo">Hello, world!</h1>;
// 等同於
const ele = React.createElement(
  "h1", //標簽名
  { className: "echo" }, //標簽屬性
  "Hello, world!" //子節點內容
);

React.createElement()本質上是創建了一個類似於如下的React對象,react會讀取並編譯這些對象,用它們構建頁面dom並實時保持更新:

const ele = {
  type: 'h1',
  props: {
    className: 'echo',
    children: 'Hello, world!'
  }
};

當然這里我們先不用了解的太深,只用知道jsx大致做了什么,以及為什么react中能這么寫就足夠了,它們的轉換過程其實是react元素經過bable轉譯--->React.createElement()調用--->react對象--->真實dom。而接下來的語法介紹我想大家會十分熟悉。

react元素支持賦予給變量,比如文章開頭的例子也可以寫成這樣:

const ele = <h1>Hello, world!</h1>;
ReactDOM.render(ele, document.getElementById("root"));

當然,react元素支持嵌套,但需要注意的是,如果我們的結構需要換行,官方推薦使用圓括號包裹你的結構,比如:

const ele = (
    <div>
        <h1>Hello World!</h1>
        <h1>My name's echo!</h1>
    </div>
);
ReactDOM.render(ele, document.getElementById("root"));

這樣做的好處是能避免代碼壓縮遇到自動插入分號的陷阱。

在vue開發中,我們習慣使用模板語法{{}}解析變量,表達式,調用方法等等,其實在react中你同樣能這么做,比如:

const myName = "echo";
const add = function (a, b) {
  return a + b;
};

const ele = (
  <div>
    <h1>my name is {myName}</h1>
    <h1>{add(2, 2)}</h1>
    <h1>{2 + 2}</h1>
  </div>
);
ReactDOM.render(ele, document.getElementById("root"));

html標簽有屬性,react元素與標簽一樣,同樣也支持標簽屬性以及自定義,比如下面的例子:

const img = "https://pic.cnblogs.com/avatar/1213309/20200507225901.png";
const ele = (
  <div>
    <div id="icon">頭像</div>
    <img src={img} alt="icon" />
  </div>
);
ReactDOM.render(ele, document.getElementById("root"));

這里需要注意的是,不要在{}外添加引號,如果你需要解析變量,請使用{},如果它只是一個字符串,那么請添加引號,二者選其一添加,兩者不要同時使用。

最后,當添加一個jsx結構時只能有一個react根元素,這點與angularjs的自定義指令模板,vue的組件只能有一個根元素情況類似,比如下面這段代碼就是錯誤示范:

const ele = (
  <div>1</div>
  <div>2</div>
);

正確的做法是為這兩個元素添加一個共有的根元素:

const ele = (
  <div>
      <div>1</div>
      <div>2</div>
  </div>
);

但請不要將這些jsx的結構理解成react組件,它們只是一些react元素構成的代碼塊,組件會有專門的方式去創建,這個后面會具體介紹,當然組件也會利用react元素來構建必要的dom結構。

肆 ❀ 元素渲染的不變性

按照我們以往的框架使用經驗,當模板語法解析的某個變量發生改變時,頁面會自動更新這個變量。但在react中,元素渲染都是一次性的,渲染成功后修改變量,頁面並不會有改變,請看下面這個例子:

let num = 0;
setInterval(function () {
  num++;
}, 1000);

setInterval(function () {
  //控制台輸出num
  console.log(num);
}, 1000);

const ele = <div>{num}</div>;
ReactDOM.render(ele, document.getElementById("root"));

打開控制台,你會發現num在不斷自增,而頁面結構中解析的num依舊是0,並沒有任何變化,這是因為ReactDOM.render就是一次性執行,它只會調用了一次,因此沒辦法及時更新num,比較直接的辦法是可以將render整個過程也包裹在定時器中,比如:

let num = 0;
setInterval(function () {
  num++;
}, 1000);

setInterval(function () {
  //利用定時器不斷更新react元素,以及讓render重復渲染
  const ele = <div>{num}</div>;
  ReactDOM.render(ele, document.getElementById("root"));
}, 1000);

這樣做能達到效果,但直觀感受這種做法並不友好,其實在后續文檔中,react有提供狀態專門用於解決這個問題,當然這都是后話了。

其次,我們雖然用定時器反復執行render,但神奇的是react在每次更新dom時,對比新舊dom結構,並只更新發生變化的部分,打開瀏覽器控制台,觀察dom變化就非常清楚了。這一點相對我之前使用的angularjs,就非常人性化了...

伍 ❀ 總

那么到這里,我們成功在本地搭建了一個屬於自己的應用,並了解了react中jsx語法,以及一些常見的用法。學習完這些內容,我們可以利用react元素構建出一些簡單的靜態頁面,雖然現在還未涉及組件概念,當然這些將會在后續文章中展開。

不知不覺又凌晨一點了,這篇文章就先寫到這里,那么本文結束。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM