新聞中心
我在給別人培訓(xùn) React 的過程中得出這樣的一個結(jié)論:React 完全是關(guān)于 JavaScript 的。而且,有很多材料是關(guān)于 JavaScript 而不是 React。其中大部分是 JavaScript ES6 及其特性和語法,還包括三元運算符、簡化的語法、this 對象、JavaScript 內(nèi)置函數(shù)(map、reduce、filter)或更一般的概念,如可組合性、可重用性、不變性或高階函數(shù)。在剛開始接觸 React 之前,你可能不需要掌握這些基礎(chǔ)知識,但在學(xué)習(xí)或?qū)嵺`過程中肯定需要用到它們。這篇文章列出了大部分有用的 JavaScript 特性,將在你學(xué)習(xí) React 的過程中助你一臂之力。

10年積累的網(wǎng)站設(shè)計、網(wǎng)站制作經(jīng)驗,可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識你,你也不認(rèn)識我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有威寧免費網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
在開始 React 之前先學(xué)習(xí) JavaScript
當(dāng)你開始進入 React 的世界,create-react-app(https://github.com/facebook/create-react-app)通常會是你的***個 React 項目。在搭建好項目后,你將看到下面的這個 React 類組件:
- import React, { Component } from 'react';
- import logo from './logo.svg';
- import './App.css';
- class App extends Component {
- render() {
- return (
![]()
Welcome to React
- To get started, edit
src/App.jsand save to reload.- );
- }
- }
- export default App;
React 類組件可能不是***的入手點。新手有許多東西需要消化,不一定與 React 有關(guān):類語句、類方法和繼承。導(dǎo)入語句也會在學(xué)習(xí) React 時增加額外的復(fù)雜性。盡管主要焦點應(yīng)該放在 JSX(React 的語法)上,但其他的東西也需要解釋一番。這篇文章主要針對 JavaScript,所以請不用太擔(dān)心 React 相關(guān)的內(nèi)容。
React 和 JavaScript 類
關(guān)于 React 類組件,需要用到有關(guān) JavaScript 類的先驗知識。JavaScript 類的概念相對較新。之前,只有 JavaScript 的原型鏈可用于實現(xiàn)繼承。JavaScript 類以原型繼承為基礎(chǔ),讓繼承體系變得更簡單。
定義 React 組件的一種方法是使用 JavaScript 類。
- class Developer {
- constructor(firstname, lastname) {
- this.firstname = firstname;
- this.lastname = lastname;
- }
- getName() {
- return this.firstname + ' ' + this.lastname;
- }
- }
- var me = new Developer('Robin', 'Wieruch');
- console.log(me.getName());
一個類描述了一個實體,用于創(chuàng)建實體的實例。在使用 new 語句創(chuàng)建類的實例時,會調(diào)用這個類的構(gòu)造函數(shù)。類的屬性通常位于構(gòu)造函數(shù)中。此外,類方法(例如 getName())用于讀取(或?qū)懭耄嵗臄?shù)據(jù)。類的實例在類中使用 this 對象來表示,但在外部,僅指定給 JavaScript 變量。
在面向?qū)ο缶幊讨?,類通常用來實現(xiàn)繼承。在 JavaScript 中也一樣,extends 語句可用于讓一個類繼承另一個類。一個子類通過 extends 語句繼承了一個父類的所有功能,還可以添加自己的功能。
- class Developer {
- constructor(firstname, lastname) {
- this.firstname = firstname;
- this.lastname = lastname;
- }
- getName() {
- return this.firstname + ' ' + this.lastname;
- }
- }
- class ReactDeveloper extends Developer {
- getJob() {
- return 'React Developer';
- }
- }
- var me = new ReactDeveloper('Robin', 'Wieruch');
- console.log(me.getName());
- console.log(me.getJob());
基本上,要理解 React 的類組件,知道這些就夠了。JavaScript 類用于定義 React 組件,React 組件繼承了從 React 包導(dǎo)入的 React Component 類的所有功能。
- import React, { Component } from 'react';
- class App extends Component {
- render() {
- return (
Welcome to React
- );
- }
- }
- export default App;
這就是為什么 render() 方法在 React 類組件中是必需的:從 React 包導(dǎo)入的 React Component 用它在瀏覽器中顯示某些內(nèi)容。此外,如果不從 React Component 繼承,將無法使用其他生命周期方法(包括 render() 方法)。例如,如果不繼承,那么 componentDidMount() 生命周期方法就不存在,因為現(xiàn)在這個類只是一個普通 JavaScript 類的實例。除了生命周期方法不可用,React 的 API 方法(例如用于本地狀態(tài)管理的 this.setState())也不可用。
我們可以通過 JavaScript 類來擴展通用類的行為。因此,我們可以引入自己的類方法或?qū)傩浴?/p>
- import React, { Component } from 'react';
- class App extends Component {
- getGreeting() {
- return 'Welcome to React';
- }
- render() {
- return (
{this.getGreeting()}
- );
- }
- }
- export default App;
現(xiàn)在你應(yīng)該知道為什么 React 使用 JavaScript 類來定義 React 類組件。當(dāng)你需要訪問 React 的 API(生命周期方法、this.state 和 this.setState())時,可以使用它們。接下來,你將看到如何以不同的方式定義 React 組件,比如不使用 JavaScript 類,因為有時候你可能不需要使用類方法、生命周期方法或狀態(tài)。
盡管我們可以在 React 中使用 JavaScript 類繼承,但這對于 React 來說不是一個理想的結(jié)果,因為 React 更傾向于使用組合而不是繼承。因此,你的 React 組件需要擴展的唯一類應(yīng)該是 React Component。
React 中的箭頭函數(shù)
在給別人培訓(xùn) React 時,我在一開始就向他們解釋 JavaScript 的箭頭函數(shù)。箭頭函數(shù)是 ES6 新增的語言特性之一,讓 JavaScript 向函數(shù)式編程更近了一步。
- // JavaScript ES5 function
- function getGreeting() {
- return 'Welcome to JavaScript';
- }
- // JavaScript ES6 arrow function with body
- const getGreeting = () => {
- return 'Welcome to JavaScript';
- }
- // JavaScript ES6 arrow function without body and implicit return
- const getGreeting = () =>
- 'Welcome to JavaScript';
在 React 應(yīng)用程序中使用 JavaScript 箭頭函數(shù)通常是為了讓代碼保持簡潔和可讀。我很喜歡箭頭函數(shù),總是嘗試將我的函數(shù)從 JavaScript ES5 重構(gòu)成 ES6。在某些時候,當(dāng) JavaScript ES5 函數(shù)和 JavaScript ES6 函數(shù)之間的差異很明顯時,我會使用 JavaScript ES6 的箭頭函數(shù)。不過,對 React 新手來說,太多不同的語法可能會讓人不知所措。因此,在 React 中使用它們之前,我會嘗試解釋 JavaScript 函數(shù)的不同特點。在以下部分,你將了解到如何在 React 中使用 JavaScript 箭頭函數(shù)。
在 React 中將函數(shù)視為組件
React 使用了不同的編程范式,這要歸功于 JavaScript 是一門“多面手”編程語言。在面向?qū)ο缶幊谭矫?,React 的類組件可以很好地利用 JavaScript 類(React 組件 API 的繼承、類方法和類屬性,如 this.state)。另一方面,React(及其生態(tài)系統(tǒng))也使用了很多函數(shù)式編程的概念。例如,React 的函數(shù)無狀態(tài)組件是另一種定義 React 組件的方式。那么,如果可以像函數(shù)那樣使用組件,將會怎樣?
- function (props) {
- return view;
- }
這是一個接收輸入(例如 props)并返回 HTML 元素(視圖)的函數(shù)。它不需要管理任何狀態(tài)(無狀態(tài)),也不需要了解任何方法(類方法、生命周期方法)。這個函數(shù)只需要使用 React 組件的 render() 方法來進行渲染。
- function Greeting(props) {
- return
{props.greeting}
;- }
功能無狀態(tài)組件是在 React 中定義組件的***方法。它們的樣板代碼較少,復(fù)雜性較低,并且比 React 類組件更易于維護。不過,這兩者都有自己存在的理由。
之前提到了 JavaScript 箭頭函數(shù)以及它們可以提升代碼的可讀性,現(xiàn)在讓我們將這些函數(shù)應(yīng)用無狀態(tài)組件中。之前的 Greeting 組件在 JavaScript ES5 和 ES6 中的寫法有點不一樣:
- // JavaScript ES5 function
- function Greeting(props) {
- return
{props.greeting}
;- }
- // JavaScript ES6 arrow function
- const Greeting = (props) => {
- return
{props.greeting}
;- }
- // JavaScript ES6 arrow function without body and implicit return
- const Greeting = (props) =>
{props.greeting}
JavaScript 箭頭函數(shù)是讓 React 無狀態(tài)組件保持簡潔的一個不錯的方法。
React 類組件語法
React 定義組件的方式一直在演化。在早期階段,React.createClass() 方法是創(chuàng)建 React 類組件的默認(rèn)方式?,F(xiàn)在不再使用這個方法,因為隨著 JavaScript ES6 的興起,之前的 React 類組件語法成為默認(rèn)語法。
不過,JavaScript 也在不斷發(fā)展,因此 JavaScript 愛好者一直在尋找新的方式。這就是為什么你會發(fā)現(xiàn) React 類組件使用了不同的語法。使用狀態(tài)和類方法來定義 React 類組件的一種方法如下:
- class Counter extends Component {
- constructor(props) {
- super(props);
- this.state = {
- counter: 0,
- };
- this.onIncrement = this.onIncrement.bind(this);
- this.onDecrement = this.onDecrement.bind(this);
- }
- onIncrement() {
- this.setState(state => ({ counter: state.counter + 1 }));
- }
- onDecrement() {
- this.setState(state => ({ counter: state.counter - 1 }));
- }
- render() {
- return (
{this.state.counter}
- );
- }
- }
不過,在實現(xiàn)大量的 React 類組件時,構(gòu)造函數(shù)中的類方法綁定和構(gòu)造函數(shù)本身就變成了繁瑣的實現(xiàn)細(xì)節(jié)。所運的是,有一個簡短的語法可用來擺脫這兩個煩惱:
- class Counter extends Component {
- state = {
- counter: 0,
- };
- onIncrement = () => {
- this.setState(state => ({ counter: state.counter + 1 }));
- }
- onDecrement = () => {
- this.setState(state => ({ counter: state.counter - 1 }));
- }
- render() {
- return (
{this.state.counter}
- );
- }
- }
通過使用 JavaScript 箭頭函數(shù),可以自動綁定類方法,不需要在構(gòu)造函數(shù)中綁定它們。通過將狀態(tài)直接定義為類屬性,在不使用 props 時就可以省略構(gòu)造函數(shù)。(注意:請注意,JavaScript 還不支持類屬性。)因此,你可以說這種定義 React 類組件的方式比其他版本更簡潔。
React 中的模板字面量
模板字面量是 JavaScript ES6 附帶的另一種 JavaScript 語言特性。之所以提到這個特性,是因為當(dāng) JavaScript 和 React 新手看到它們時,可能會感到困惑。以下面的連接字符串的語法為例:
- function getGreeting(what) {
- return 'Welcome to ' + what;
- }
- const greeting = getGreeting('JavaScript');
- console.log(greeting);
- // Welcome to JavaScript
模板字面量可以用于達(dá)到相同的目的,被稱為字符串插值:
- function getGreeting(what) {
- return `Welcome to ${what}`;
- }
你只需使用反引號和 ${}來插入 JavaScript 原語。字符串字面量不僅可用于字符串插值,還可用于多行字符串:
- function getGreeting(what) {
- return `
- Welcome
- to
- ${what}
- `;
- }
這樣就可以格式化多行文本塊。
React 中 Map、Reduce 和 Filter
在向 React 新手教授 JSX 語法時,我通常會先在 render() 方法中定義一個變量,然后將其用在返回代碼塊中。
- import React, { Component } from 'react';
- class App extends Component {
- render() {
- var greeting = 'Welcome to React';
- return (
{greeting}
- );
- }
- }
- export default App;
你只需使用花括號來操作 HTML 中的 JavaScript。不管是渲染字符串還是渲染一個復(fù)雜的對象,并沒有太大不同。
- import React, { Component } from 'react';
- class App extends Component {
- render() {
- var user = { name: 'Robin' };
- return (
{user.name}
- );
- }
- }
- export default App;
接下來的問題是:如何渲染項目列表?React 沒有提供特定的 API(例如 HTML 標(biāo)記的自定義屬性)用于渲染項目列表。我們可以使用純 JavaScript 代碼來迭代項目列表,并返回每個項目的 HTML。
- import React, { Component } from 'react';
- class App extends Component {
- render() {
- var users = [
- { name: 'Robin' },
- { name: 'Markus' },
- ];
- return (
- {users.map(function (user) {
- return
- {user.name}
;- })}
- );
- }
- }
- export default App;
通過使用 JavaScript 箭頭函數(shù),你可以擺脫箭頭函數(shù)體和 return 語句,讓渲染輸出更加簡潔。
- import React, { Component } from 'react';
- class App extends Component {
- render() {
- var users = [
- { name: 'Robin' },
- { name: 'Markus' },
- ];
- return (
- {users.map(user =>
- {user.name}
)}- );
- }
- }
- export default App;
很快,每個 React 開發(fā)人員都習(xí)慣了 JavaScript 內(nèi)置的 map() 方法。對數(shù)組進行 map 并返回每個項的渲染輸出,這樣做非常有用。在某系情況下,結(jié)合使用 filter() 或 reduce() 會更有用,而不只是為每個被 map 的項渲染輸出。
- import React, { Component } from 'react';
- class App extends Component {
- render() {
- var users = [
- { name: 'Robin', isDeveloper: true },
- { name: 'Markus', isDeveloper: false },
- ];
- return (
- {users
- .filter(user => user.isDeveloper)
- .map(user =>
- {user.name}
)- }
- );
- }
- }
- export default App;
通常,React 開發(fā)人員習(xí)慣于使用 JavaScript 的這些內(nèi)置函數(shù),而不必使用 React 特定的 API。它只是 HTML 中的 JavaScript。
React 中的 var、let 和 const
對于 React 的新手來說,使用 var、let 和 const 來聲明變量可能也會給他們造成混淆,雖然它們不是 React 相關(guān)的。我會嘗試在教學(xué)中盡早介紹 let 和 const,并從在 React 組件中交替使用 const 和 var 開始:
- import React, { Component } from 'react';
- class App extends Component {
- render() {
- const users = [
- { name: 'Robin' },
- { name: 'Markus' },
- ];
- return (
- {users.map(user =>
- {user.name}
)}- );
- }
- }
- export default App;
然后我給出了一些使用這些變量聲明的經(jīng)驗法則:
(1)不要使用 var,因為 let 和 const 更具體
(2)默認(rèn)使用 const,因為它不能被重新分配或重新聲明
(3)如果要重新賦值變量則使用 let
let 通常用于 for 循環(huán)中,const 通常用于保持 JavaScript 變量不變。盡管在使用 const 時可以修改對象和數(shù)組的內(nèi)部屬性,但變量聲明表達(dá)了保持變量不變的意圖。
React 中的三元運算符
如果要通過 if-else 語句進行條件渲染該怎么辦?我們不能直接在 JSX 中使用 if-else 語句,但可以從渲染函數(shù)中提前返回。如果不需要顯示內(nèi)容,返回 null 在 React 中是合法的。
- import React, { Component } from 'react';
- class App extends Component {
- render() {
- const users = [
- { name: 'Robin' },
- { name: 'Markus' },
- ];
- const showUsers = false;
- if (!showUsers) {
- return null;
- }
- return (
- {users.map(user =>
- {user.name}
)}- );
- }
- }
- export default App;
不過,如果要在返回的 JSX 中使用 if-else 語句,可以使用 JavaScript 的三元運算符:
- import React, { Component } from 'react';
- class App extends Component {
- render() {
- const users = [
- { name: 'Robin' },
- { name: 'Markus' },
- ];
- const showUsers = false;
- return (
- {
- showUsers ? (
- {users.map(user =>
- {user.name}
)}- ) : (
- null
- )
- }
- );
- }
- }
- export default App;
如果你只返回條件渲染的一個方面,可以使用 && 運算符:
- import React, { Component } from 'react';
- class App extends Component {
- render() {
- const users = [
- { name: 'Robin' },
- { name: 'Markus' },
- ];
- const showUsers = false;
- return (
- {
- showUsers && (
- {users.map(user =>
- {user.name}
)}- )
- }
- );
- }
- }
- export default App;
詳細(xì)的原理我就不說了,但如果你感興趣,可以在這篇文章(https://www.robinwieruch.de/conditional-rendering-react/)里了解到更詳細(xì)的信息以及與條件渲染相關(guān)的其他技術(shù)。React 中的條件渲染告訴我們,大多數(shù) React 都是與 JavaScript 有關(guān),而不是 React 特定的內(nèi)容。
React 中的導(dǎo)入和導(dǎo)出語句
在 JavaScript 中,我們可以通過 import 和 export 語句來導(dǎo)入和導(dǎo)出在 JavaScript ES6 文件中定義的功能。
在開始你的***個 React 應(yīng)用程序之前,這些 import 和 export 語句是另一個需要了解的話題。create-react-app 項目已經(jīng)在使用 import 語句:
- import React, { Component } from 'react';
- import logo from './logo.svg';
- import './App.css';
- class App extends Component {
- render() {
- return (
![]()
Welcome to React
- To get started, edit
src/App.jsand save to reload.- );
- }
- }
- export default App;
這對初始項目來說非常棒,因為它為你提供了一個全面的體驗,可以導(dǎo)入和導(dǎo)出其他文件。不過,在剛開始接觸 React 時,我會試著避免這些導(dǎo)入。相反,我會專注于 JSX 和 React 組件。在需要將 React 組件或 JavaScript 函數(shù)分離到單獨的文件中時,才需要引入導(dǎo)入和導(dǎo)出語句。
那么這樣使用這些導(dǎo)入和導(dǎo)出語句呢?假設(shè)你想要導(dǎo)出一個文件的如下變量:
- const firstname = 'Robin';
- const lastname = 'Wieruch';
- export { firstname, lastname };
然后,你可以通過***個文件的相對路徑將它們導(dǎo)入到另一個文件中:
- import { firstname, lastname } from './file1.js';
- console.log(firstname);
- // output: Robin
因此,它不一定只是與導(dǎo)入或?qū)С鼋M件或函數(shù)有關(guān),它可以是共享可分配給變量的所有東西(我們只談 JS)。你還可以將另一個文件導(dǎo)出的所有變量作為一個對象導(dǎo)入:
- import * as person from './file1.js';
- console.log(person.firstname);
- // output: Robin
導(dǎo)入可以有別名。當(dāng)從多個文件導(dǎo)入具有相同導(dǎo)出名稱的功能時,就需要用到別名。
- import { firstname as username } from './file1.js';
- console.log(username);
- // output: Robin
之前所有的例子都是命名的導(dǎo)入和導(dǎo)出。除此之外,還有默認(rèn)的導(dǎo)入和導(dǎo)出。它可以用于以下一些場景:
- 導(dǎo)出和導(dǎo)入單個功能;
- 強調(diào)一個模塊導(dǎo)出 API 的主要功能;
- 作為導(dǎo)入功能的后備。
- const robin = {
- firstname: 'Robin',
- lastname: 'Wieruch',
- };
- export default robin;
在使用默認(rèn)導(dǎo)入時可以省略大括號:
- import developer from './file1.js';
- console.log(developer);
- // output: { firstname: 'Robin', lastname: 'Wieruch' }
此外,導(dǎo)入名稱可以與導(dǎo)出的默認(rèn)名稱不同。你還可以將它與命名的 export 和 import 語句一起使用:
- const firstname = 'Robin';
- const lastname = 'Wieruch';
- const person = {
- firstname,
- lastname,
- };
- export {
- firstname,
- lastname,
- };
- export default person;
在另一個文件中導(dǎo)入:
- import developer, { firstname, lastname } from './file1.js';
- console.log(developer);
- // output: { firstname: 'Robin', lastname: 'Wieruch' }
- console.log(firstname, lastname);
- // output: Robin Wieruch
你還可以節(jié)省一些行,直接導(dǎo)出命名的變量:
- export const firstname = 'Robin';
- export const lastname = 'Wieruch';
這些是 ES6 模塊的主要功能。它們可以幫助你更好地組織代碼,并設(shè)計出可重用的模塊 API。
React 中的庫
React 只是應(yīng)用程序的視圖層。React 提供了一些內(nèi)部狀態(tài)管理,但除此之外,它只是一個為瀏覽器渲染 HTML 的組件庫。API(例如瀏覽器 API、DOM API)、JavaScript 或外部庫可以為 React 添加額外的東西。為 React 應(yīng)用程序選擇合適的庫并不是件容易的事,但一旦你對不同的庫有了很好的了解,就可以選擇最適合你的技術(shù)棧的庫。
例如,我們可以使用 React 原生的獲取數(shù)據(jù)的 API 來獲取數(shù)據(jù):
- import React, { Component } from 'react';
- class App extends Component {
- state = {
- data: null,
- };
- componentDidMount() {
- fetch('https://api.mydomain.com')
- .then(response => response.json())
- .then(data => this.setState({ data }));
- }
- render() {
- ...
- }
- }
- export default App;
但你也可以使用另一個庫來獲取數(shù)據(jù),Axios 就是這樣的一個流行庫:
- import React, { Component } from 'react';
- import axios from 'axios';
- class App extends Component {
- state = {
- data: null,
- };
- componentDidMount() {
- axios.get('https://api.mydomain.com')
- .then(data => this.setState({ data }));
- }
- render() {
- ...
- }
- }
- export default App;
因此,一旦你知道了需要解決什么問題,React 的生態(tài)系統(tǒng)就可以為你提供大量的解決方案。這可能與 React 本身無關(guān),而是有關(guān)了解如何選擇可用于彌補 React 應(yīng)用程序的各種 JavaScript 庫。
React 中的高階函數(shù)
高階函數(shù)是函數(shù)式編程中的一個非常棒的概念。在 React 中,了解這些函數(shù)是非常有意義的,因為在某些時候你需要處理高階組件,如果已經(jīng)了解了高階函數(shù),那么就可以更好地了解這些高階組件。
我們假設(shè)可以根據(jù)一個輸入字段的值對用戶列表進行過濾。
- import React, { Component } from 'react';
- class App extends Component {
- state = {
- query: '',
- };
- onChange = event => {
- this.setState({ query: event.target.value });
- }
- render() {
- const users = [
- { name: 'Robin' },
- { name: 'Markus' },
- ];
- return ( <
名稱欄目:在開始React之前,你需要學(xué)好這些JavaScript
文章鏈接:http://fisionsoft.com.cn/article/dpopjsc.html


咨詢
建站咨詢
