在理想的情況中,您可以先了解所有有關 JavaScript 和 web 開發的知識,然後再深入瞭解React。 但是,我們沒有辦法這樣,如果等你把所有 JavaScript 的知識都掌握了再去學習 React,就會浪費很多時間。 如果您已經有一些使用 JavaScript 的經驗,那麼在 學習 React 之前您需要學習的只是能夠實際應用於開發 React 應用程式的 JavaScript 知識。那些掌握下面這些 JavaScript 知識點,就足夠你去學習 React。
- ES6 的類
- 宣告變數 let/const
- 箭頭函式
- 解構賦值
- Map and filter
- ES6 模組系統
您將在 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 中引入了兩個新的變數宣告:即 let
和 const
。它們都是相同的,用於宣告變數。 不同之處在於,const
不能在宣告後更改其值,而 let
可以。兩個宣告都是本地的,這意味著如果您在函式範圍內宣告 let
,則不能在函式外部呼叫它。
const name = "David";
let age = 28;
var occupation = "Software Engineer";
使用哪一個?
經驗法則是預設情況下使用 const
宣告變數。稍後,當您編寫應用程式時,您將意識到 const
的值需要更改,那個時候你應該想著把 const
重構成 let
。您應該去習慣使用 const
或 let
。
我們什麼時候在 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 開發人員,從一個常規函式語法轉到箭頭語法一開始可能會不舒服。
當我學習箭頭函式時,我使用了這兩個簡單的步驟來重寫我的函式:
- 刪除 function 關鍵字
- 在 () 之後新增箭頭符號 =>
括號仍然用於傳遞引數,如果只有一個引數,則可以省略括號。
// 兩個引數
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 物件的 firstName
和 lastName
分配給了新變數 firstName
和 lastName
.
現在,如果您想將 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