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

在理想的情況中,您可以先了解所有有關 JavaScript 和 web 開發的知識,然後再深入瞭解React。 但是,我們沒有辦法這樣,如果等你把所有 JavaScript 的知識都掌握了再去學習 React,就會浪費很多時間。 如果您已經有一些使用 JavaScript 的經驗,那麼在 學習 React 之前您需要學習的只是能夠實際應用於開發 React 應用程序的 JavaScript 知識。那些掌握下面這些 JavaScript 知識點,就足夠你去學習 React。

您將在 80% 的時間內使用 20% 的 JavaScript功能,因此在本教程中,我將幫助您學習所有這些功能。

探索 Create React App 腳手架

在開始學習 React 之前我們都用 create-react-app 這個腳手架來創建 React 應用,它具有運行 React 的一切基礎套件。

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 類:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <p>
            Edit <code>src/App.js</code> and save to reload.
          </p>
          <a
            className="App-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
          >
            Learn React
          </a>
        </header>
      </div>
    );
  }
}

export default App;

如果你以前從未學過 ES6,你會認爲這個類語句是 React 的一個特性。

這實際上是 ES6 的一個新功能,這就是爲什麼正確學習 ES6 可以讓你更好地理解 React 代碼。

我們將從 ES6 課程開始:

ES6 類

ES6 引入了類語法,其使用方式與面嚮對象語言類似,如 Java 或 python,ES6中的基礎類如下所示:

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 就是構造函數,當用這個類創建一個新的對象時就會用這個方法。 傳遞到該構造函數的任何參數都將傳遞到新對象。

例如:

// Nathan 會傳給 constructor 方法,最終 this.name 等於 Nathan
var nathan = new Developer('Nathan');

nathan.hello(); // Hello World! I am Nathan and I am a web developer

一個類可以根據需要定義儘可能多的方法,在這種情況下,我們有返回字符串的 hello 方法。

類繼承

一個類可以繼承另一個類,並且從該類初始化的新對象將具有兩個類的所有方法。

// 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 函數:

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 組件類。

// 從 react 庫導入 React 組件類,還有 Component 類
import React, { Component } from 'react';

// 我們自己定義的組件繼承 上面導入的 Component 類
class App extends Component {
  // class content
  render(){
    return (
      <h1>Hello React!</h1>
    )
  }
}

因爲我們自己定義的 App 組件繼承自從 react 庫中導入 Component 類,所以我們也具有 Component 類的一些方法,比如 render() 方法,還有 this.state 這些屬性。但是後面你可能會看到,類並不是我們唯一定義組件的方式,如果你不需要 state(一種狀態數據), 還有組件的生命週期方法,你可以用函數來代替類的。

使用 ES6 let 和 const 聲明變量

以前都是用 var 關鍵字在 JavaScript 中聲明變量,ES6 中引入了兩個新的變量聲明:即 letconst。它們都是相同的,用於聲明變量。 不同之處在於,const 不能在聲明後更改其值,而 let 可以。兩個聲明都是本地的,這意味着如果您在函數範圍內聲明 let,則不能在函數外部調用它。

const name = "David";
let age = 28;
var occupation = "Software Engineer";

使用哪一個?

經驗法則是默認情況下使用 const 聲明變量。稍後,當您編寫應用程序時,您將意識到 const 的值需要更改,那個時候你應該想着把 const 重構成 let。您應該去習慣使用 constlet

我們什麼時候在 React 中使用它?

每次我們需要變量的時候,看看以下示例:

import React, { Component } from 'react';

class App extends Component {
  // class content
  render(){
		// 在這裏使用變理
    const greeting = 'Welcome to React';

    return (
      <h1>{greeting}</h1>
    )
  }
}

由於 greeting 在整個應用程序生命週期中不會改變,我們在這裏使用 const 定義它。

箭頭函數

箭頭函數是一個新的 ES6 特性,在現代代碼庫中幾乎被廣泛使用,因爲它保持代碼簡潔和可讀。

此語法允許我們使用更短的語法編寫函數:

// regular function
const testFunction = function() {
  // content..
}

// arrow function
const testFunction = () => {
  // content..
}

如果你是一個有經驗的 JS 開發人員,從一個常規函數語法轉到箭頭語法一開始可能會不舒服。

當我學習箭頭函數時,我使用了這兩個簡單的步驟來重寫我的函數:

  1. 刪除 function 關鍵字
  2. 在 () 之後添加箭頭符號 =>

括號仍然用於傳遞參數,如果只有一個參數,則可以省略括號。

// 兩個參數
const testFunction = (firstName, lastName) => {
  return firstName+' '+lastName;
}

// 一個參數時可以省略括號
const singleParam = firstName => {
  return firstName;
}

隱式返回

如果您的箭頭函數只有一行,您可以直接返回值,而不必使用 return 關鍵字和花括號 {}

// 直接返回,不用寫 {} 和 return
const testFunction = () => 'hello there.';
testFunction();

在 React 中使用

創建 React 組件的另一種方法是使用箭頭函數。

React 組件箭頭函數寫法:

const HelloWorld = (props) => {
  return <h1>{props.hello}</h1>;
}

相當於 ES6 類組件

class HelloWorld extends Component {
  render() {
    return (
      <h1>{props.hello}</h1>;
    );
  }
}

在您的 React 應用程序中使用箭頭函數使代碼更加簡潔, 因爲它也將從組件中刪除 state 的使用。

這種類型的組件被稱爲無狀態功能組件。

你會在許多 React 教程中找到這個名字。

數組和對象的解構分配

ES6中引入的最有用的新語法之一,解構賦值就是簡單地複製對象或數組的一部分,並將它們放入命名變量中。

一個簡單的例子:

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 對象的 firstNamelastName 分配給了新變量 firstNamelastName.

現在,如果您想將 firstName 換成名爲 name 的新變量,怎麼辦?

// : 後面加變量別名
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 數據的解構,例子:

reactFunction = () => {
  const { name, email } = this.state;
};

或者在無狀態組件中:

const HelloWorld = (props) => {
  return <h1>{props.hello}</h1>;
}

我們可以簡單地立即解構參數:

const HelloWorld = ({ hello }) => {
  return <h1>{hello}</h1>;
}

解構數組用於 React 的 useState Hook:

const [user, setUser] = useState('');

Map 和 filter

儘管本教程側重於 ES6,但需要提及 JavaScript 數組映射和過濾器方法,因爲它們可能是構建 React 應用程序時最常用的 ES5 功能之一,尤其是處理數據。

這兩種方法更多地用於處理數據。例如,假設從 遠程API 獲取結果返回 JSON 數據數組:

const users = [
  { name: 'Nathan', age: 25 },
  { name: 'Jack', age: 30 },
  { name: 'Joe', age: 28 },
];

然後,我們可以在 React 中呈現項目列表,如下所示:

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 (
      <ul>
        {users
          .map(user => <li>{user.name}</li>)
        }
      </ul>
    )
  }
}

我們還可以過濾渲染中的數據。

<ul>
  {users
    .filter(user => user.age > 26)
    .map(user => <li>{user.name}</li>)
  }
</ul>

ES6 模塊系統

ES6 模塊系統使 JavaScript 能夠導入和導出文件。

爲了解釋這一點,讓我們再次看看 src/app.js 代碼。

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <p>
            Edit <code>src/App.js</code> and save to reload.
          </p>
          <a
            className="App-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
          >
            Learn React
          </a>
        </header>
      </div>
    );
  }
}

export default App;

在代碼的第一行,我們看到了導入語句:

import React, { Component } from 'react';

在最後一行,我們看到了導出默認 (export default) 語句:

爲了理解這些語句,讓我們先討論一下模塊語法。

模塊只是一個 JavaScript 文件,它使用 export 關鍵字導出一個或多個值 (可以是對象、函數或變量)。

首先,在 src 目錄中創建一個名爲 util.js 的新文件

然後在裏面寫一個函數,這是 默認導出(export default)

export default function times(x) {
  return x * x;
}

或多個命名導出

export function times(x) {
  return x * x;
}

export function plusTwo(number) {
  return number + 2;
}

然後我們可以從 src/App.js 導入它

// 從 util.js 文件中導入
import { times, plusTwo } from './util.js';

console.log(times(2));
console.log(plusTwo(3));

每個模塊可以有多個命名導出,但只有一個默認導出。

可以導入默認導出,而無需使用花括號和相應的導出函數名稱:

// 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

但是對於命名導出,您必須使用花括號和確切名稱進行導入。

或者,導入可以使用別名來避免對兩個不同的導入使用相同的名稱:

// 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';

從絕對名稱導入,如:

import React from 'react';

將對根目錄下的 node_modules 目錄進行 JavaScript 檢查以獲取相應的包名稱。

因此,如果要導入本地文件,請不要忘記使用正確的路徑。

在 React 中使用

很明顯,我們在 index.js 中看到導入了 App 組件:

//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.render(<App />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
serviceWorker.unregister();

請注意:從 .js 擴展名導入時,可以忽略擴展名的輸寫。

import App from './App';

總結

React 最大的好處是它不會像其他 web 框架一樣在 JavaScript 之上添加任何外部抽象層,這就是爲什麼React在JS開發人員中變得非常受歡迎,它只是使用最好的 JavaScript 使構建用戶界面更容易和可維護。在一個 React 應用程序中,一旦你掌握好上面所講的 JavaScript 知識,你就可以自信地編寫 React 應用,併成爲一個優秀的程序員。

翻譯自:Nathan Sebhastian 原文:https://dev.to/nsebhastian/javascript-basics-before-you-learn-react-38en

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章