學習React之前你需要知道的的JavaScript基礎知識

zcfy發表於2018-07-26

  在我的研討會期間,更多的材料是關於JavaScript而不是React。其中大部分歸結為JavaScript ES6以及功能和語法,但也包括三元運算子,語言中的簡寫版本,此物件,JavaScript內建函式(map,reduce,filter)或更常識性的概念,如:可組合性,可重用性,不變性或高階函式。這些是基礎知識,在開始使用React之前你不需要掌握這些基礎知識,但在學習或實踐它時肯定會出現這些基礎知識。

  以下演練是我嘗試為您提供一個幾乎廣泛但簡明的列表,其中列出了所有不同的JavaScript功能,以補充您的React應用程式。如果您有任何其他不在列表中的內容,只需對本文發表評論,我會及時更新。

 目錄

 從JavaScript中學習React

  當你進入React的世界時,通常是使用用於啟動React專案的 create-react-app。設定專案後,您將遇到以下React類元件:

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

class App extends Component {
  render() {
    return (
      <div>
        <header>
          <img src alt="logo" />
          <h1>Welcome to React</h1>
        </header>
        <p>
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
      </div>
    );
  }
}

export default App;

  可以說,React類元件可能不是最好的起點。新手有許多東西需要消化,不一定是React:類語句,類方法和繼承。匯入語句也只是在學習React時增加了複雜性。儘管主要焦點應該是JSX(React的語法),但通常所有的事情都需要解釋。這篇文章應該揭示所有的東西,大部分是JavaScript,而不用擔心React。

 React和JavaScript類

  在開始時遇到React類元件,需要有關JavaScript類的基礎只是。JavaScript類在語言中是相當新的。以前,只有JavaScript的原型鏈也可以用於繼承。JavaScript類在原型繼承之上構建,使整個事物更簡單。

  定義React元件的一種方法是使用JavaScript類。為了理解JavaScript類,您可以花一些時間在沒有React的情況下學習它們。

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());

  類描述了一個實體,該實體用作建立該實體例項的藍圖。一旦使用new語句建立了類的例項,就會呼叫該類的建構函式,該例項化該類的例項。因此,類可以具有通常位於其建構函式中的屬性。此外,類方法(例如getName())用於讀取(或寫入)例項的資料。類的例項在類中表示為此物件,但例項外部僅指定給JavaScript變數。

  通常,類用於物件導向程式設計中的繼承。它們在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元件,因為它繼承了從React包匯入的React Component類的所有功能。

import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
      <div>
        <h1>Welcome to React</h1>
      </div>
    );
  }
}

export default App;

  這就是為什麼render()方法在React類元件中是必需的:來自匯入的React包的React元件指示您使用它在瀏覽器中顯示某些內容。此外,如果不從React元件擴充套件,您將無法使用其他生命週期方法 (包括render()方法)。例如,不存在componentDidMount()生命週期方法,因為該元件將是vanilla JavaScript類的例項。並且不僅生命週期方法會消失,React的API方法(例如用於本地狀態管理的this.setState())也不可用。

  但是,正如您所看到的,使用JavaScript類有利於使用您的專業行為擴充套件通用類。因此,您可以引入自己的類方法或屬性。

import React, { Component } from 'react';

class App extends Component {
  getGreeting() {
    return 'Welcome to React';
  }

  render() {
    return (
      <div>
        <h1>{this.getGreeting()}</h1>
      </div>
    );
  }
}

export default App;

  現在您知道為什麼React使用JavaScript類來定義React類元件。當您需要訪問React的API(生命週期方法,this.state和this.setState())時,可以使用它們。在下文中,您將看到如何以不同的方式定義React元件,而不使用JavaScript類,因為您可能不需要始終使用類方法,生命週期方法和狀態。

  畢竟,JavaScript類歡迎使用React中的繼承,這對於React來說不是一個理想的結果,因為React更喜歡組合而不是繼承。因此,您應該為您的React元件擴充套件的唯一類應該是官方的React元件。

 React中的箭頭函式

  When teaching someone about React, I explain JavaScript arrow functions pretty early. They are one of JavaScript’s language additions in ES6 which pushed JavaScript forward in functional programming.

  在教關於React時,我很早就解釋了JavaScript arrow functions。它們是ES6中JavaScript的語言新增之一,它推動了JavaScript在函數語言程式設計中的發展。

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

  JavaScript箭頭函式通常用在React應用程式中,以保持程式碼簡潔和可讀。嘗試從JavaScript ES5到ES6功能重構我的功能。在某些時候,當JavaScript ES5函式和JavaScript ES6函式之間的差異很明顯時,我堅持使用JavaScript ES6的方式來實現箭頭函式。但是,我總是看到React新手的太多不同的語法可能會讓人不知所措。因此,我嘗試在使用它們在React中全部使用之前,使JavaScript函式的不同特性變得清晰。在以下部分中,您將瞭解如何在React中常用JavaScript箭頭函式。

 作為React中的元件的function

  React使用不同的程式設計範例,因為JavaScript是一種多方面的程式語言。在物件導向程式設計的時候,React的類元件是利用JavaScript類這一種方式(React元件API的繼承,類方法和類屬性,如this.state)。另一方面,React(及其生態系統)中使用了很多的函數語言程式設計的概念。例如,React的功能無狀態元件是另一種在React中定義元件的方法。在React無狀態元件就引發了一個新的思考:元件如何像函式一樣使用?

function (props) {
  return view;
}

  它是一個接收輸入(例如props)並返回顯示的HTML元素(檢視)的函式(函式)。它不需要管理任何狀態(無狀態),也不需要了解任何方法(類方法,生命週期方法)。該函式只需要使用React元件中render()方法的呈現機制。那是在引入無狀態元件的時候。

function Greeting(props) {
  return <h1>{props.greeting}</h1>;
}

  無狀態元件是在React中定義元件的首選方法。它們具有較少的樣板,降低了複雜性,並且比React類元件更易於維護。但是,就目前而言,兩者都有自己存在的意義。

  以前,文章提到了JavaScript箭頭函式以及它們如何改進您的React程式碼。讓我們將這些函式應用於您的無狀態元件。 來看看Greeting組分別使用ES5和ES6不同的寫法:

// JavaScript ES5 function
function Greeting(props) {
  return <h1>{props.greeting}</h1>;
}

// JavaScript ES6 arrow function
const Greeting = (props) => {
  return <h1>{props.greeting}</h1>;
}

// JavaScript ES6 arrow function without body and implicit return
const Greeting = (props) =>
  <h1>{props.greeting}</h1>

  JavaScript箭頭函式是在React中保持無狀態元件簡潔的好方法。當更多的時候沒有計算,因此可以省略函式體和return語句。

 React類元件語法

  React定義元件的方式隨著時間的推移而演變。在早期階段,React.createClass()方法是建立React類元件的預設方式。如今,它已不再使用,因為隨著JavaScript ES6的興起,更多的是使用ES6的方法來建立React類元件。

  然而,JavaScript不斷髮展,因此JavaScript愛好者一直在尋找新的做事方式。這就是為什麼你會經常發現React類元件的不同語法。使用狀態和類方法定義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 (
      <div>
        <p>{this.state.counter}</p>

        <button onClick={this.onIncrement} type="button">Increment</button>
        <button onClick={this.onDecrement} type="button">Decrement</button>
      </div>
    );
  }
}

  但是,當實現大量的React類元件時,建構函式中的class方法的繫結 以及首先具有建構函式變為繁瑣的實現細節。幸運的是,有一個簡短的語法來擺脫這兩個煩惱:

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 (
      <div>
        <p>{this.state.counter}</p>

        <button onClick={this.onIncrement} type="button">Increment</button>
        <button onClick={this.onDecrement} type="button">Decrement</button>
      </div>
    );
  }
}

  通過使用JavaScript箭頭函式,您可以自動繫結類方法,而無需在建構函式中繫結它們。通過將狀態直接定義為類屬性,也可以在不使用props時省略建構函式。 (注意:請注意,類屬性 尚未使用JavaScript語言。)因此,您可以說這種定義React類元件的方式比其他版本更簡潔。

 React中的模板文字

  模板文字是JavaScript ES6附帶的另一種JavaScript語言特定功能。值得一提的是,因為當JavaScript和React的新手看到它們時,它們也會讓人感到困惑。以下是你正在用的連線字串的語法:

function getGreeting(what) {
  return 'Welcome to ' + what;
}

const greeting = getGreeting('JavaScript');
console.log(greeting);
// Welcome to JavaScript

  模板文字可以用於相同的文字文字,稱為字串插值:

function getGreeting(what) {
  return Welcome to ${what};
}

  您只需使用` `和${}表示法來插入JavaScript原語。但是,字串文字不僅用於字串插值,還用於JavaScript中的多行字串:

function getGreeting(what) {
  return 
    Welcome
    to
    ${what}
  ;
}

  基本上,這就是如何在多行上格式化更大的文字塊。最近在JavaScript中引入了GraphQL也可以看出它

 React中的Map, Reduce 和 Filter

  為React新手教授JSX語法的最佳方法是什麼?通常我首先在render()方法中定義一個變數,並在返回塊中將其用作HTML中的JavaScript。

import React, { Component } from 'react';

class App extends Component {
  render() {
    var greeting = 'Welcome to React';
    return (
      <div>
        <h1>{greeting}</h1>
      </div>
    );
  }
}

export default App;

  您只需使用花括號來獲取HTML格式的JavaScript。從渲染字串到複雜物件並沒有什麼不同。

import React, { Component } from 'react';

class App extends Component {
  render() {
    var user = { name: 'Robin' };
    return (
      <div>
        <h1>{user.name}</h1>
      </div>
    );
  }
}

export default App;

  通常接下來的問題是:如何呈現一個專案列表?在我看來,這是解釋React最好的部分之一。沒有特定於React的API,例如HTML標記上的自定義屬性,使您可以在React中呈現多個專案。您可以使用純JavaScript來迭代專案列表並返回每個專案的HTML。

import React, { Component } from 'react';

class App extends Component {
  render() {
    var users = [
      { name: 'Robin' },
      { name: 'Markus' },
    ];

    return (
      <ul>
        {users.map(function (user) {
          return <li>{user.name}</li>;
        })}
      </ul>
    );
  }
}

export default App;

  之前使用過JavaScript箭頭函式,你可以擺脫箭頭函式體和return語句,使你的渲染輸出更加簡潔。

import React, { Component } from 'react';

class App extends Component {
  render() {
    var users = [
      { name: 'Robin' },
      { name: 'Markus' },
    ];

    return (
      <ul>
        {users.map(user => <li>{user.name}</li>)}
      </ul>
    );
  }
}

export default App;

  很快,每個React開發人員都習慣了陣列的內建JavaScript map()方法。對映陣列並返回每個項的渲染輸出非常有意義。這同樣適用於自定義的情況,其中filter()或reduce()更有意義,而不是為每個對映項呈現輸出。

import React, { Component } from 'react';

class App extends Component {
  render() {
    var users = [
      { name: 'Robin', isDeveloper: true },
      { name: 'Markus', isDeveloper: false },
    ];

    return (
      <ul>
        {users
          .filter(user => user.isDeveloper)
          .map(user => <li>{user.name}</li>)
        }
      </ul>
    );
  }
}

export default App;

  通常,這就是React開發人員如何習慣這些JavaScript內建函式,而不必使用React特定的API。它只是HTML中的JavaScript。

 React中的var,let和const

  使用var,let和const的不同變數宣告對於React的新手來說可能會造成混淆,即使它們不是React特定的。也許是因為當React變得流行時引入了JavaScript ES6。總的來說,我嘗試在我的工作室中儘早介紹let和const。它只是從在React元件中與const交換var開始:

import React, { Component } from 'react';

class App extends Component {
  render() {
    const users = [
      { name: 'Robin' },
      { name: 'Markus' },
    ];

    return (
      <ul>
        {users.map(user => <li>{user.name}</li>)}
      </ul>
    );
  }
}

export default App;

  然後我給出了使用哪個變數宣告的經驗法則:

  • (1)不要使用var,因為let和const更具體
  • (2)預設為const,因為它不能重新分配或重新宣告
  • (3)重新賦值變數時使用let

  雖然let通常用於for迴圈來遞增迭代器,但const通常用於保持JavaScript變數不變。儘管在使用const時可以更改物件和陣列的內部屬性,但變數宣告顯示了保持變數不變的意圖。

 React中的三目運算子

  如果要在render中的JSX中使用if-else語句,可以使用JavaScripts三元運算子來執行此操作:

import React, { Component } from 'react';

class App extends Component {
  render() {
    const users = [
      { name: 'Robin' },
      { name: 'Markus' },
    ];

    const showUsers = false;

    if (!showUsers) {
      return null;
    }

    return (
      <ul>
        {users.map(user => <li>{user.name}</li>)}
      </ul>
    );
  }
}

export default App;

import React, { Component } from 'react';

class App extends Component {
  render() {
    const users = [
      { name: 'Robin' },
      { name: 'Markus' },
    ];

    const showUsers = false;

    return (
      <div>
        {
          showUsers ? (
            <ul>
              {users.map(user => <li>{user.name}</li>)}
            </ul>
          ) : (
            null
          )
        }
      </div>
    );
  }
}

export default App;

  另一種方法是,如果你只返回條件渲染的一邊,則使用&&運算子:

import React, { Component } from 'react';

class App extends Component {
  render() {
    const users = [
      { name: 'Robin' },
      { name: 'Markus' },
    ];

    const showUsers = false;

    return (
      <div>
        {
          showUsers && (
            <ul>
              {users.map(user => <li>{user.name}</li>)}
            </ul>
          )
        }
      </div>
    );
  }
}

export default App;

  我不會詳細說明為什麼會這樣,但如果你很好奇,你可以在這裡瞭解它和條件渲染的其他技術:React中的所有條件渲染。畢竟,React中的條件呈現僅再次顯示大多數React是JavaScript而不是React特定的任何內容。

 React中的Import 和 Export語句

  幸運的是,JavaScript社群確定了使用JavaScript ES6的importexport

  但是,對於React和JavaScript ES6來說,這些匯入和匯出語句只是另一個需要在開始使用第一個React應用程式時需要解釋的主題。很早就有了CSS,SVG或其他JavaScript檔案的第一次匯入。 create-react-app專案已經從那些import語句開始:

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

class App extends Component {
  render() {
    return (
      <div>
        <header>
          <img src alt="logo" />
          <h1>Welcome to React</h1>
        </header>
        <p>
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
      </div>
    );
  }
}

export default App;

  這對初學者專案來說非常棒,因為它為您提供了一個全面的體驗,可以匯入和匯出其他檔案。 App元件也會在 src/index.js檔案中匯入。但是,在React中執行第一步時,我會嘗試在開始時避免這些匯入。相反,我嘗試專注於JSX和React元件。只有在將另一個檔案中的第一個React元件或JavaScript函式分離時才會引入匯入和匯出語句。

  那麼這些匯入和匯出語句如何工作呢?假設您要在一個檔案中匯出以下變數:

const firstname = 'Robin';
const lastname = 'Wieruch';

export { firstname, lastname };

  然後,您可以使用第一個檔案的相對路徑將它們匯入到另一個檔案中:

import { firstname, lastname } from './file1.js';

console.log(firstname);
// output: Robin

  因此,它不一定是關於 importing/exporting 元件或函式,而是關於共享可分配給變數的所有東西(省略CSS或SVG匯入/匯出,但只談JS)。您還可以將另一個檔案中的所有匯出變數作為一個物件匯入:

import * as person from './file1.js';

console.log(person.firstname);
// output: Robin

  importing可以有別名。您可能會從具有相同命名匯出的多個檔案中匯入功能。這就是你可以使用別名的原因:

import { firstname as username } from './file1.js';

console.log(username);
// output: Robin

  以前的所有案例都被命名為進口和出口。但是也存在預設宣告。它可以用於一些用例:

  • 匯出和匯入單個功能
  • 突出顯示模組的匯出API的主要功能
  • 具有後備匯入功能
const robin = {
  firstname: 'Robin',
  lastname: 'Wieruch',
};

export default robin;

  您可以省略匯入的大括號以匯入預設匯出:

import developer from './file1.js';

console.log(developer);
// output: { firstname: 'Robin', lastname: 'Wieruch' }

  此外,匯入名稱可能與匯出的預設名稱不同。您還可以將它與命名的export和import語句一起使用:

const firstname = 'Robin';
const lastname = 'Wieruch';

const person = {
  firstname,
  lastname,
};

export {
  firstname,
  lastname,
};

export default person;

  並在另一個檔案中匯入預設匯出或命名匯出:

import developer, { firstname, lastname } from './file1.js';

console.log(developer);
// output: { firstname: 'Robin', lastname: 'Wieruch' }
console.log(firstname, lastname);
// output: Robin Wieruch

  您還可以節省額外的行並直接為命名匯出匯出變數:

export const firstname = 'Robin';
export const lastname = 'Wieruch';

  這些是ES6模組的主要功能。它們可以幫助您組織程式碼,維護程式碼和設計可重用的模組API。您還可以匯出和匯入功能以測試它們。

 React中的庫

  React只是應用程式的檢視層。 React提供了一些內部狀態管理,但除此之外,它只是一個為您的瀏覽器呈現HTML的元件庫。其他所有內容都可以從API(例如瀏覽器API,DOM API),JavaScript功能或外部庫中新增。選擇合適的庫來補充React應用程式並不總是很簡單,但是一旦您對不同的選項有了很好的概述,就可以選擇最適合您的技術堆疊的庫。

  例如,可以使用本機fetch API在React中獲取資料:

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;

  但是你可以使用另一個庫來獲取React中的資料。 Axios是React應用程式的一個流行選擇:

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廣泛而創新的生態系統應該為您提供大量解決方案 。這又不是關於React,而是瞭解所有可用於補充應用程式的不同JavaScript庫。

 React中的高階函式

  高階函式是一個很好的程式設計概念,特別是在轉向函數語言程式設計時。在React中,瞭解這類函式是完全有意義的,因為在某些時候你必須處理高階元件,這些元件在首先了解高階函式時可以得到最好的解釋。

  可以在早期的React中展示高階函式,而不會引入更高階的元件。例如,假設可以根據輸入欄位的值過濾呈現的使用者列表。

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

        <input
          type="text"
          onChange={this.onChange}
        />
      </div>
    );
  }
}

export default App;

  並不總是希望提取函式,因為它可以增加不必要的複雜性,但另一方面,它可以為JavaScript帶來有益的學習效果。此外,通過提取函式,您可以將其與React元件隔離開來進行測試。因此,讓我們使用提供給內建過濾器功能的功能來展示它。

import React, { Component } from 'react';

function doFilter(user) {
  return this.state.query === user.name;
}

class App extends Component {
  ...

  render() {
    const users = [
      { name: 'Robin' },
      { name: 'Markus' },
    ];

    return (
      <div>
        <ul>
          {users
            .filter(doFilter)
            .map(user => <li>{user.name}</li>)
          }
        </ul>

        <input
          type="text"
          onChange={this.onChange}
        />
      </div>
    );
  }
}

export default App;

  之前的實現不起作用,因為doFilter()函式需要從狀態知道查詢屬性。因此,您可以通過將其包含在另一個導致更高階函式的函式中來將其傳遞給函式。

import React, { Component } from 'react';

function doFilter(query) {
  return function (user) {
    return this.state.query === user.name;
  }
}

class App extends Component {
  ...

  render() {
    const users = [
      { name: 'Robin' },
      { name: 'Markus' },
    ];

    return (
      <div>
        <ul>
          {users
            .filter(doFilter(this.state.query))
            .map(user => <li>{user.name}</li>)
          }
        </ul>

        <input
          type="text"
          onChange={this.onChange}
        />
      </div>
    );
  }
}

export default App;

  基本上,高階函式是返回函式的函式。通過使用JavaScript ES6箭頭函式,您可以使更高階的函式更簡潔。此外,這種速記版本使得將功能組合成功能更具吸引力。

const doFilter = query => user =>
  this.state.query === user.name;

  現在可以從檔案中匯出doFilter()函式,並將其作為純(高階)函式單獨測試。在瞭解了高階函式之後,建立了所有基礎知識,以便更多地瞭解React的高階元件

  將這些函式提取到React元件之外的(高階)函式中也可以有利於單獨測試React的本地狀態管理。

export const doIncrement = state =>
  ({ counter: state.counter + 1 });

export const doDecrement = state =>
  ({ counter: state.counter - 1 });

class Counter extends Component {
  state = {
    counter: 0,
  };

  onIncrement = () => {
    this.setState(doIncrement);
  }

  onDecrement = () => {
    this.setState(doDecrement);
  }

  render() {
    return (
      <div>
        <p>{this.state.counter}</p>

        <button onClick={this.onIncrement} type="button">Increment</button>
        <button onClick={this.onDecrement} type="button">Decrement</button>
      </div>
    );
  }
}

  圍繞程式碼庫移動函式是瞭解在JavaScript中使用函式作為拳頭類公民的好處的好方法。將程式碼移向函數語言程式設計時,它非常強大。

 React中的解構和傳播運算子

  JavaScript中引入的另一種語言特性稱為解構。通常情況下,您必須從您state或元件中的props訪問大量屬性。您可以在JavaScript中使用解構賦值,而不是逐個將它們分配給變數。

// no destructuring
const users = this.state.users;
const counter = this.state.counter;

// destructuring
const { users, counter } = this.state;

  這對功能無狀態元件特別有用,因為它們總是在函式簽名中接收props物件。通常,您不會使用道具而是使用道具,因此您可以對功能簽名中已有的內容進行解構。

// no destructuring
function Greeting(props) {
  return <h1>{props.greeting}</h1>;
}

// destructuring
function Greeting({ greeting }) {
  return <h1>{greeting}</h1>;
}

  解構也適用於JavaScript陣列。另一個很棒的特徵是其餘的解構。它通常用於拆分物件的一部分,但將剩餘屬性保留在另一個物件中。

// rest destructuring
const { users, ...rest } = this.state;

  之後,可以使用使用者進行渲染,例如在React元件中,而在其他地方使用剩餘的狀態。這就是JavaScript擴充套件運算子 用於將其餘物件轉發到下一個元件的位置。在下一節中,您將看到此運算子的執行情況。

 JavaScript比React更重要

  總之,有很多JavaScript可以在React中使用。雖然React只有一個API表面區域,但開發人員必須習慣JavaScript提供的所有功能。這句話並非沒有任何理由:“成為React開發人員會讓你成為更好的JavaScript開發人員”。讓我們通過重構更高階的元件來回顧一下React中JavaScript的一些學習方面。

function withLoading(Component) {
  return class WithLoading extends {
    render() {
      const { isLoading, ...props } = this.props;

      if (isLoading) {
        return <p>Loading</p>;
      }

      return <Component { ...props } />;
    }
  }
  };
}

  當isLoading prop設定為true時,此高階元件僅用於顯示條件載入指示符。否則它呈現輸入元件。您已經可以看到(休息)解構和傳播運算子。後者可以在渲染的Component中看到,因為props物件的所有剩餘屬性都傳遞給Component。

  使高階元件更簡潔的第一步是將返回的React類元件重構為功能無狀態元件:

function withLoading(Component) {
  return function ({ isLoading, ...props }) {
    if (isLoading) {
      return <p>Loading</p>;
    }

    return <Component { ...props } />;
  };
}

您可以看到其餘的解構也可以在函式的簽名中使用。接下來,使用JavaScript ES6箭頭函式使高階元件更簡潔:

const withLoading = Component => ({ isLoading, ...props }) => {
  if (isLoading) {
    return <p>Loading</p>;
  }

  return <Component { ...props } />;
}

  新增三元運算子可將函式體縮短為一行程式碼。因此可以省略函式體,並且可以省略return語句。

const withLoading = Component => ({ isLoading, ...props }) =>
  isLoading
    ? <p>Loading</p>
    : <Component { ...props } />

  如您所見,高階元件使用各種JavaScript而不是React相關技術:箭頭函式,高階函式,三元運算子,解構和擴充套件運算子。這就是如何在React應用程式中使用JavaScript的功能。


  人們經常說學習React的學習曲線很陡峭。但是,只有將React留在等式中並將所有JavaScript排除在外。當其他Web框架正在執行時,React不會在頂部新增任何外部抽象層。相反,你必須使用JavaScript。因此,磨練您的JavaScript技能,您將成為一個偉大的React開發人員。

  原文連結: www.robinwieruch.de

相關文章