<li id="2aw4k"></li>
  • <div id="2aw4k"><tr id="2aw4k"></tr></div>
  • <div id="2aw4k"><tr id="2aw4k"></tr></div>
    <center id="2aw4k"><small id="2aw4k"></small></center><center id="2aw4k"><small id="2aw4k"></small></center>
    首頁»JavaScript»學習React之前你需要知道的的JavaScript基礎知識

    學習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

    QQ群:WEB開發者官方群(515171538),驗證消息:10000
    微信群:加小編微信 849023636 邀請您加入,驗證消息:10000
    提示:更多精彩內容關注微信公眾號:全棧開發者中心(fsder-com)
    網友評論(共0條評論) 正在載入評論......
    理智評論文明上網,拒絕惡意謾罵 發表評論 / 共0條評論
    登錄會員中心
    大乐透彩票预测
    <li id="2aw4k"></li>
  • <div id="2aw4k"><tr id="2aw4k"></tr></div>
  • <div id="2aw4k"><tr id="2aw4k"></tr></div>
    <center id="2aw4k"><small id="2aw4k"></small></center><center id="2aw4k"><small id="2aw4k"></small></center>
    <li id="2aw4k"></li>
  • <div id="2aw4k"><tr id="2aw4k"></tr></div>
  • <div id="2aw4k"><tr id="2aw4k"></tr></div>
    <center id="2aw4k"><small id="2aw4k"></small></center><center id="2aw4k"><small id="2aw4k"></small></center>