1. 程式人生 > >2021 年學習 React 的所需要的 JavaScript 基礎

2021 年學習 React 的所需要的 JavaScript 基礎

![](https://pro.qiuzhi99.com/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBWDg9IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--04593a8d29cc42ca70b254e02f5a5491a8917e0a/image.png) 在理想的情況中,您可以先了解所有有關 JavaScript 和 web 開發的知識,然後再深入瞭解React。 但是,我們沒有辦法這樣,如果等你把所有 JavaScript 的知識都掌握了再去學習 React,就會浪費很多時間。 如果您已經有一些使用 JavaScript 的經驗,那麼在 學習 React 之前您需要學習的只是能夠實際應用於開發 React 應用程式的 JavaScript 知識。那些掌握下面這些 JavaScript 知識點,就足夠你去學習 React。 - [ES6 ](#es6-classes)的類 - 宣告變數 let/const - 箭頭函式 - 解構賦值 - [Map and filter](#map-and-filter) - [ES6 ](#es6-module-system)模組系統 您將在 80% 的時間內使用 20% 的 JavaScript功能,因此在本教程中,我將幫助您學習所有這些功能。 ## 探索 Create React App 腳手架 在開始學習 React 之前我們都用 `create-react-app` 這個腳手架來建立 React 應用,它具有執行 React 的一切基礎套件。 [https://reactjs.org/docs/create-a-new-react-app.html](https://reactjs.org/docs/create-a-new-react-app.html) ``` npx create-react-app my-app cd my-app npm start ``` 然後,在該過程完成後,開啟 `src/app.js` 檔案,將向我們展示整個應用程式中唯一的 React 類: ```javascript import React, { Component } from 'react'; import logo from './logo.svg'; import './App.css'; class App extends Component { render() { return (

Edit src/App.js and save to reload.

Learn React
); } } export default App; ``` 如果你以前從未學過 ES6,你會認為這個類語句是 React 的一個特性。 這實際上是 ES6 的一個新功能,這就是為什麼正確學習 ES6 可以讓你更好地理解 React 程式碼。 我們將從 ES6 課程開始: ## ES6 類 ES6 引入了類語法,其使用方式與面嚮物件語言類似,如 Java 或 python,ES6中的基礎類如下所示: ```javascript class Developer { // 建構函式,建立新物件時(new),呼叫 // name 是引數,可以根據需要,定義多個引數 constructor(name){ this.name = name; } // 方法 hello(){ return 'Hello World! I am ' + this.name + ' and I am a web developer'; } } ``` `class` 後面跟著類的名稱,這個類(有點像模板)可以用於建立一個新的物件。這個 `constructor` 就是建構函式,當用這個類建立一個新的物件時就會用這個方法。 傳遞到該建構函式的任何引數都將傳遞到新物件。 例如: ```javascript // Nathan 會傳給 constructor 方法,最終 this.name 等於 Nathan var nathan = new Developer('Nathan'); nathan.hello(); // Hello World! I am Nathan and I am a web developer ``` 一個類可以根據需要定義儘可能多的方法,在這種情況下,我們有返回字串的 `hello` 方法。 ### 類繼承 一個類可以繼承另一個類,並且從該類初始化的新物件將具有兩個類的所有方法。 ```javascript // ReactDeveloper 繼承了 Developer 這個類 class ReactDeveloper extends Developer { installReact(){ return 'installing React .. Done.'; } } // 用子類生成了新物件 var nathan = new ReactDeveloper('Nathan'); // 子類物件 nathan 將具有子類與父類的所有方法 nathan.hello(); // Hello World! I am Nathan and I am a web developer nathan.installReact(); // installing React .. Done. ``` 繼承另一個類的類通常稱為子類,被繼承的類稱為父類或超類。 子類還可以覆蓋父類中定義的方法,這意味著它將用定義的新方法替換父類方法。 例如,讓我們覆蓋 hello 函式: ```javascript class ReactDeveloper extends Developer { installReact(){ return 'installing React .. Done.'; } // Developer 類也有 hello 方法,這裡直接重寫覆蓋 hello(){ return 'Hello World! I am ' + this.name + ' and I am a REACT developer'; } } var nathan = new ReactDeveloper('Nathan'); // 這裡呼叫的將是子類覆蓋後的方法 nathan.hello(); // Hello World! I am Nathan and I am a REACT developer ``` 這樣,`Developer` 類中的 `hello` 方法已被覆蓋。 ### 在 React 中使用 現在我們瞭解了ES6類和繼承,我們可以瞭解 `src/app.js` 中定義的 React 類. 這是一個 React 元件,但它實際上只是一個普通的 ES6 類,繼承了從 `react` 這個庫裡匯入的 React 元件類。 ```javascript // 從 react 庫匯入 React 元件類,還有 Component 類 import React, { Component } from 'react'; // 我們自己定義的元件繼承 上面匯入的 Component 類 class App extends Component { // class content render(){ return (

Hello React!

) } } ``` 因為我們自己定義的 App 元件繼承自從 `react` 庫中匯入 Component 類,所以我們也具有 Component 類的一些方法,比如 `render()` 方法,還有 `this.state` 這些屬性。但是後面你可能會看到,類並不是我們唯一定義元件的方式,如果你不需要 `state`(一種狀態資料), 還有元件的生命週期方法,你可以用函式來代替類的。 ## 使用 ES6 let 和 const 宣告變數 以前都是用 `var` 關鍵字在 JavaScript 中宣告變數,ES6 中引入了兩個新的變數宣告:即 `let` 和 `const`。它們都是相同的,用於宣告變數。 不同之處在於,`const `不能在聲明後更改其值,而 `let` 可以。兩個宣告都是本地的,這意味著如果您在函式範圍內宣告 `let`,則不能在函式外部呼叫它。 ```javascript const name = "David"; let age = 28; var occupation = "Software Engineer"; ``` ### 使用哪一個? 經驗法則是預設情況下使用 `const` 宣告變數。稍後,當您編寫應用程式時,您將意識到 `const` 的值需要更改,那個時候你應該想著把 `const` 重構成 `let`。您應該去習慣使用 `const` 或 `let`。 ### 我們什麼時候在 React 中使用它? 每次我們需要變數的時候,看看以下示例: ```javascript import React, { Component } from 'react'; class App extends Component { // class content render(){ // 在這裡使用變理 const greeting = 'Welcome to React'; return (

{greeting}

) } } ``` 由於 `greeting` 在整個應用程式生命週期中不會改變,我們在這裡使用 `const` 定義它。 ## 箭頭函式 箭頭函式是一個新的 ES6 特性,在現代程式碼庫中幾乎被廣泛使用,因為它保持程式碼簡潔和可讀。 此語法允許我們使用更短的語法編寫函式: ```javascript // regular function const testFunction = function() { // content.. } // arrow function const testFunction = () => { // content.. } ``` 如果你是一個有經驗的 JS 開發人員,從一個常規函式語法轉到箭頭語法一開始可能會不舒服。 當我學習箭頭函式時,我使用了這兩個簡單的步驟來重寫我的函式: 1. 刪除 function 關鍵字 2. 在 () 之後新增箭頭符號 => 括號仍然用於傳遞引數,如果只有一個引數,則可以省略括號。 ```javascript // 兩個引數 const testFunction = (firstName, lastName) => { return firstName+' '+lastName; } // 一個引數時可以省略括號 const singleParam = firstName => { return firstName; } ``` ### 隱式返回 如果您的箭頭函式只有一行,您可以直接返回值,而不必使用 `return` 關鍵字和花括號 `{}` ```javascript // 直接返回,不用寫 {} 和 return const testFunction = () => 'hello there.'; testFunction(); ``` ### 在 React 中使用 建立 React 元件的另一種方法是使用箭頭函式。 React 元件箭頭函式寫法: ```javascript const HelloWorld = (props) => { return

{props.hello}

; } ``` 相當於 ES6 類元件 ```javascript class HelloWorld extends Component { render() { return (

{props.hello}

; ); } } ``` 在您的 React 應用程式中使用箭頭函式使程式碼更加簡潔, 因為它也將從元件中刪除 `state` 的使用。 這種型別的元件被稱為無狀態功能元件。 你會在許多 React 教程中找到這個名字。 ## 陣列和物件的解構分配 ES6中引入的最有用的新語法之一,解構賦值就是簡單地複製物件或陣列的一部分,並將它們放入命名變數中。 一個簡單的例子: ```javascript const developer = { firstName: 'Nathan', lastName: 'Sebhastian', developer: true, age: 25, } //destructure developer object // 從 developer 物件中取出資料的簡單寫法 const { firstName, lastName } = developer; console.log(firstName); // returns 'Nathan' console.log(lastName); // returns 'Sebhastian' console.log(developer); // returns the object ``` 如您所見,我們將 developer 物件的 `firstName` 和 `lastName` 分配給了新變數 `firstName` 和 `lastName`. 現在,如果您想將 `firstName` 換成名為 `name` 的新變數,怎麼辦? ```javascript // : 後面加變數別名 const { firstName: name } = developer; console.log(name); // returns 'Nathan' ``` 解構也適用於陣列,只有它使用索引而不是物件鍵: ``` const numbers = [1,2,3,4,5]; const [one, two] = numbers; // one = 1, two = 2 ``` 您能夠用 `,` 將某些鍵跳過: ``` const [one, two, , four] = numbers; // one = 1, two = 2, four = 4 ``` ### 在 React 中使用 主要用 `state` 資料的解構,例子: ```javascript reactFunction = () => { const { name, email } = this.state; }; ``` 或者在無狀態元件中: ``` const HelloWorld = (props) => { return

{props.hello}

; } ``` 我們可以簡單地立即解構引數: ``` const HelloWorld = ({ hello }) => { return

{hello}

; } ``` 解構陣列用於 React 的 useState Hook: ``` const [user, setUser] = useState(''); ``` ## Map 和 filter 儘管本教程側重於 ES6,但需要提及 JavaScript 陣列對映和過濾器方法,因為它們可能是構建 React 應用程式時最常用的 ES5 功能之一,尤其是處理資料。 這兩種方法更多地用於處理資料。例如,假設從 遠端API 獲取結果返回 JSON 資料陣列: ```javascript const users = [ { name: 'Nathan', age: 25 }, { name: 'Jack', age: 30 }, { name: 'Joe', age: 28 }, ]; ``` 然後,我們可以在 React 中呈現專案列表,如下所示: ```javascript import React, { Component } from 'react'; class App extends Component { // class content render(){ const users = [ { name: 'Nathan', age: 25 }, { name: 'Jack', age: 30 }, { name: 'Joe', age: 28 }, ]; return (
    {users .map(user =>
  • {user.name}
  • ) }
) } } ``` 我們還可以過濾渲染中的資料。 ```html
    {users .filter(user => user.age > 26) .map(user =>
  • {user.name}
  • ) }
``` ## ES6 模組系統 ES6 模組系統使 JavaScript 能夠匯入和匯出檔案。 為了解釋這一點,讓我們再次看看 `src/app.js` 程式碼。 ```javascript import React, { Component } from 'react'; import logo from './logo.svg'; import './App.css'; class App extends Component { render() { return (

Edit src/App.js and save to reload.

Learn React
); } } export default App; ``` 在程式碼的第一行,我們看到了匯入語句: ``` import React, { Component } from 'react'; ``` 在最後一行,我們看到了匯出預設 (export default) 語句: 為了理解這些語句,讓我們先討論一下模組語法。 模組只是一個 JavaScript 檔案,它使用 export 關鍵字匯出一個或多個值 (可以是物件、函式或變數)。 首先,在 `src` 目錄中建立一個名為 `util.js` 的新檔案 然後在裡面寫一個函式,這是 預設匯出(export default) ```javascript export default function times(x) { return x * x; } ``` 或多個命名匯出 ```javascript export function times(x) { return x * x; } export function plusTwo(number) { return number + 2; } ``` 然後我們可以從 `src/App.js` 匯入它 ```javascript // 從 util.js 檔案中匯入 import { times, plusTwo } from './util.js'; console.log(times(2)); console.log(plusTwo(3)); ``` 每個模組可以有多個命名匯出,但只有一個預設匯出。 可以匯入預設匯出,而無需使用花括號和相應的匯出函式名稱: ```javascript // in util.js export default function times(x) { return x * x; } // in app.js import k from './util.js'; console.log(k(4)); // returns 16 ``` 但是對於命名匯出,您必須使用花括號和確切名稱進行匯入。 或者,匯入可以使用別名來避免對兩個不同的匯入使用相同的名稱: ```javascript // in util.js export function times(x) { return x * x; } export function plusTwo(number) { return number + 2; } // in app.js import { times as multiplication, plusTwo as plus2 } from './util.js'; ``` 從絕對名稱匯入,如: ```javascript import React from 'react'; ``` 將對根目錄下的 `node_modules` 目錄進行 JavaScript 檢查以獲取相應的包名稱。 因此,如果要匯入本地檔案,請不要忘記使用正確的路徑。 ### 在 React 中使用 很明顯,我們在 `index.js` 中看到匯入了 App 元件: ```javascript //index.js file import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import * as serviceWorker from './serviceWorker'; ReactDOM