JavaScript >> Javascript 文檔 >  >> React

React 教程:概述和演練

自從我第一次開始學習 JavaScript 以來,我就一直聽說 Rea​​ct,但我承認我看過它,它嚇到了我。我看到看起來像是一堆混合了 JavaScript 的 HTML 並想,這不是我們一直在努力避免的嗎? React 有什麼大不了的?

相反,我專注於學習 vanilla JavaScript 並在專業環境中使用 jQuery。在嘗試開始使用 React 的一些挫折和失敗嘗試之後,我終於開始掌握它,並且我開始明白為什麼我可能想要使用 React 而不是 vanilla JS 或 jQuery。

我試圖將我學到的所有內容濃縮成一個很好的介紹與你分享,所以就在這裡。

先決條件

在開始使用 React 之前,您應該提前了解一些事情。例如,如果你以前從未使用過 JavaScript 或 DOM,那麼在嘗試處理 React 之前,我會更加熟悉它們。

以下是我認為的 React 先決條件。

  • 基本熟悉 HTML 和 CSS。
  • JavaScript 和編程的基本知識。
  • 對 DOM 的基本了解。
  • 熟悉 ES6 語法和特性。
  • Node.js 和 npm 已全局安裝。

目標

  • 了解基本的 React 概念和相關術語,例如 Babel、Webpack、JSX、組件、道具、狀態和生命週期。
  • 構建一個非常簡單的 React 應用來演示上述概念。

這是最終結果的源代碼和現場演示。

  • 在 GitHub 上查看源代碼
  • 查看演示

什麼是 React?

  • React 是一個 JavaScript 庫 - 最受歡迎的庫之一,在 GitHub 上有超過 100,000 顆星。
  • React 不是一個框架(不像 Angular,後者更加固執己見)。
  • React 是 Facebook 創建的一個開源項目。
  • React 用於在前端構建用戶界面 (UI)。
  • React 是 視圖 MVC 應用程序的層(模型視圖控制器)

React 最重要的方面之一是您可以創建 組件 ,就像自定義的、可重用的 HTML 元素一樣,可以快速有效地構建用戶界面。 React 還使用 state 簡化了數據的存儲和處理方式 和道具 .

我們將在整篇文章中介紹所有這些以及更多內容,所以讓我們開始吧。

設置和安裝

有幾種方法可以設置 React,我將向您展示其中兩種,以便您更好地了解它是如何工作的。

靜態 HTML 文件

第一種方法不是設置 React 的流行方法,也不是我們將在本教程的其餘部分中使用的方法,但如果你曾經使用過 jQuery 之類的庫,它會很熟悉且易於理解,而且它是如果您不熟悉 Webpack、Babel 和 Node.js,那麼最不可怕的入門方式。

讓我們從製作一個基本的index.html開始 文件。我們將在 head 中加載三個 CDN - React、React DOM 和 Babel。我們還將製作一個 div 具有名為 root 的 id ,最後我們將創建一個 script 標記您的自定義代碼所在的位置。

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />

    <title>Hello React!</title>

    <script src="https://unpkg.com/react@^16/umd/react.production.min.js"></script>
    <script src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>
    <script src="https://unpkg.com/[email protected]/babel.js"></script>
  </head>

  <body>
    <div id="root"></div>

    <script type="text/babel">
      // React code will go here
    </script>
  </body>
</html>

截至撰寫本文時,我正在加載最新的穩定版本的庫。

  • React - React 頂級 API
  • React DOM - 添加特定於 DOM 的方法
  • Babel - 一個 JavaScript 編譯器,讓我們可以在舊瀏覽器中使用 ES6+

我們應用的入口點將是 root div 元素,按約定命名。您還會注意到 text/babel script 類型,使用 Babel 時必須的。

現在,讓我們編寫我們的第一個 React 代碼塊。我們將使用 ES6 類創建一個名為 App 的 React 組件 .

index.html
class App extends React.Component {
  //...
}

現在我們將添加 render() 方法,類組件中唯一需要的方法,用於渲染DOM節點。

index.html
class App extends React.Component {
  render() {
      return (
          //...
      );
  }
}

return裡面 ,我們將放置一個看起來像簡單的 HTML 元素的東西。請注意,我們在這裡沒有返回字符串,所以不要在元素周圍使用引號。這稱為 JSX ,我們很快就會了解更多。

index.html
class App extends React.Component {
  render() {
    return <h1>Hello world!</h1>
  }
}

最後,我們將使用 React DOM render() 渲染 App 的方法 我們在 root 中創建的類 div 在我們的 HTML 中。

index.html
ReactDOM.render(<App />, document.getElementById('root'))

這是我們的 index.html 的完整代碼 .

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />

    <title>Hello React!</title>

    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/[email protected]/babel.js"></script>
  </head>

  <body>
    <div id="root"></div>

    <script type="text/babel">
      class App extends React.Component {
        render() {
          return <h1>Hello world!</h1>
        }
      }

      ReactDOM.render(<App />, document.getElementById('root'))
    </script>
  </body>
</html>

現在,如果您查看 index.html 在瀏覽器中,您會看到 h1 我們創建的標籤渲染到 DOM。

涼爽的!現在你已經完成了這個,你可以看到 React 開始並沒有那麼可怕。這只是我們可以加載到 HTML 中的一些 JavaScript 幫助程序庫。

我們這樣做是為了演示,但從這裡開始,我們將使用另一種方​​法:創建 React 應用程序。

創建 React 應用

我剛剛使用的將 JavaScript 庫加載到靜態 HTML 頁面並動態渲染 React 和 Babel 的方法效率不高,並且難以維護。

幸運的是,Facebook 已經創建了 Create React App,這是一個預先配置了構建 React 應用程序所需的一切的環境。它將創建一個實時開發服務器,使用 Webpack 自動編譯 React、JSX 和 ES6,自動為 CSS 文件添加前綴,並使用 ESLint 測試和警告代碼中的錯誤。

設置 create-react-app ,在您的終端中運行以下代碼,該目錄位於您希望項目所在位置的上一級目錄。

npx create-react-app react-tutorial

安裝完成後,移動到新創建的目錄並啟動項目。

cd react-tutorial && npm start

運行此命令後,將在 localhost:3000 處彈出一個新窗口 使用您的新 React 應用程序。

如果你查看項目結構,你會看到一個 /public/src 目錄,以及常規的 node_modules , .gitignore , README.md , 和 package.json .

/public ,我們的重要文件是index.html ,與靜態的 index.html 非常相似 我們之前製作的文件 - 只是一個 root 分區。這一次,沒有加載任何庫或腳本。/src 目錄將包含我們所有的 React 代碼。

要查看環境如何自動編譯和更新您的 React 代碼,請在 /src/App.js 中找到如下所示的行 :

To get started, edit `src/App.js` and save to reload.

並將其替換為任何其他文本。保存文件後,您會注意到 localhost:3000 用新數據編譯和刷新。

繼續刪除 /src 中的所有文件 目錄,我們將創建我們自己的樣板文件,而不會有任何膨脹。我們只保留 index.cssindex.js .

對於 index.css ,我只是將 Primitive CSS 的內容複製並粘貼到文件中。如果你願意,你可以使用 Bootstrap 或任何你想要的 CSS 框架,或者什麼都不用。我只是覺得使用起來更容易。

現在在 index.js ,我們正在導入 React、ReactDOM 和 CSS 文件。

src/index.js
import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'

讓我們創建我們的 App 再次組件。之前,我們只有一個 <h1> ,但現在我也添加了一個帶有類的 div 元素。你會注意到我們使用 className 而不是 class .這是我們第一次暗示這裡編寫的代碼是 JavaScript,而不是真正的 HTML。

src/index.js
class App extends React.Component {
  render() {
    return (
      <div className="App">
        <h1>Hello, React!</h1>
      </div>
    )
  }
}

最後,我們將渲染 App 像以前一樣到根目錄。

src/index.js
ReactDOM.render(<App />, document.getElementById('root'))

這是我們完整的 index.js .這一次,我們正在加載 Component 作為 React 的一個屬性,所以我們不再需要擴展 React.Component .

src/index.js
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import './index.css'

class App extends Component {
  render() {
    return (
      <div className="App">
        <h1>Hello, React!</h1>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('root'))

如果你回到 localhost:3000 ,你會看到“你好,React!”就像從前一樣。我們現在有了一個 React 應用程序的開始。

React 開發者工具

有一個名為 React Developer Tools 的擴展,它可以讓你在使用 React 時更輕鬆。下載適用於 Chrome 的 React DevTools,或者您喜歡使用的任何瀏覽器。

安裝後,當你打開 DevTools 時,你會看到一個 React 選項卡。單擊它,您將能夠在編寫組件時檢查它們。您仍然可以轉到 Elements 選項卡來查看實際的 DOM 輸出。現在看起來可能沒什麼大不了的,但隨著應用程序變得越來越複雜,它會變得越來越有必要使用。

現在我們擁有了真正開始使用 React 所需的所有工具和設置。

JSX:JavaScript + XML

如您所見,我們一直在 React 代碼中使用看起來像 HTML 的東西,但它並不完全是 HTML。這是 JSX ,代表 JavaScript XML。

使用 JSX,我們可以編寫看起來像 HTML 的東西,也可以創建和使用我們自己的類似 XML 的標籤。這是 JSX 分配給變量的樣子。

JSX
const heading = <h1 className="site-heading">Hello, React</h1>

使用 JSX 不是編寫 React 的強制要求。在引擎蓋下,它正在運行 createElement ,它獲取組件的標籤、包含屬性的對象和子組件,並呈現相同的信息。下面的代碼將與上面的 JSX 有相同的輸出。

沒有 JSX
const heading = React.createElement('h1', { className: 'site-heading' }, 'Hello, React!')

JSX 實際上更接近於 JavaScript,而不是 HTML,因此在編寫時需要注意一些關鍵差異。

  • className 用於代替 class 用於添加 CSS 類,如 class 是 JavaScript 中的保留關鍵字。
  • JSX 中的屬性和方法是駝峰式 - onclick 將變為 onClick .
  • 自閉標籤必須 以斜線結尾 - 例如<img />

JavaScript 表達式也可以使用花括號嵌入到 JSX 中,包括變量、函數和屬性。

const name = 'Tania'
const heading = <h1>Hello, {name}</h1>

JSX 比在原生 JavaScript 中創建和添加許多元素更容易編寫和理解,這也是人們如此喜愛 React 的原因之一。

組件

到目前為止,我們已經創建了一個組件 - App 零件。 React 中幾乎所有東西都由組件組成,可以是類組件簡單組件 .

大多數 React 應用程序都有許多小組件,所有內容都加載到主 App 零件。組件也經常有自己的文件,所以讓我們改變我們的項目來做到這一點。

刪除 App 來自 index.js 的類 ,所以看起來像這樣。

src/index.js
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import './index.css'

ReactDOM.render(<App />, document.getElementById('root'))

我們將創建一個名為 App.js 的新文件 並將組件放在那裡。

src/App.js
import React, { Component } from 'react'

class App extends Component {
  render() {
    return (
      <div className="App">
        <h1>Hello, React!</h1>
      </div>
    )
  }
}

export default App

我們將組件導出為 App 並將其加載到 index.js .將組件分成文件不是強制性的,但如果不這樣做,應用程序將開始變得笨拙和失控。

類組件

讓我們創建另一個組件。我們將創建一個表。製作 Table.js ,並用以下數據填充它。

src/Table.js
import React, { Component } from 'react'

class Table extends Component {
  render() {
    return (
      <table>
        <thead>
          <tr>
            <th>Name</th>
            <th>Job</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>Charlie</td>
            <td>Janitor</td>
          </tr>
          <tr>
            <td>Mac</td>
            <td>Bouncer</td>
          </tr>
          <tr>
            <td>Dee</td>
            <td>Aspiring actress</td>
          </tr>
          <tr>
            <td>Dennis</td>
            <td>Bartender</td>
          </tr>
        </tbody>
      </table>
    )
  }
}

export default Table

我們創建的這個組件是一個自定義類組件。我們利用自定義組件來區分它們與常規 HTML 元素。返回 App.js ,我們可以在表中加載,首先將其導入:

src/App.js
import Table from './Table'

然後將其加載到 render() App ,在我們有“你好,反應!”之前的地方。我也改了外容器的類。

src/App.js
import React, { Component } from 'react'
import Table from './Table'

class App extends Component {
  render() {
    return (
      <div className="container">
        <Table />
      </div>
    )
  }
}

export default App

如果您重新檢查您的實時環境,您會看到 Table 載入中。

現在我們已經了解了自定義類組件是什麼。我們可以一遍又一遍地重用這個組件。但是,由於數據是硬編碼到其中的,目前它不會太有用。

簡單組件

React 中的另一類組件是 簡單組件 ,這是一個函數。該組件不使用 class 關鍵詞。讓我們來看看我們的 Table 並為其製作兩個簡單的組件——一個表頭和一個表體。

我們將使用 ES6 箭頭函數來創建這些簡單的組件。一、表頭。

src/Table.js
const TableHeader = () => {
  return (
    <thead>
      <tr>
        <th>Name</th>
        <th>Job</th>
      </tr>
    </thead>
  )
}

然後是身體。

src/Table.js
const TableBody = () => {
  return (
    <tbody>
      <tr>
        <td>Charlie</td>
        <td>Janitor</td>
      </tr>
      <tr>
        <td>Mac</td>
        <td>Bouncer</td>
      </tr>
      <tr>
        <td>Dee</td>
        <td>Aspiring actress</td>
      </tr>
      <tr>
        <td>Dennis</td>
        <td>Bartender</td>
      </tr>
    </tbody>
  )
}

現在我們的 Table 文件將如下所示。請注意,TableHeaderTableBody 組件都在同一個文件中,並被 Table 使用 類組件。

src/Table.js
const TableHeader = () => { ... }
const TableBody = () => { ... }

class Table extends Component {
  render() {
    return (
      <table>
        <TableHeader />
        <TableBody />
      </table>
    )
  }
}

一切都應該像以前一樣出現。可以看到,組件可以嵌套在其他組件中,簡單和類組件可以混用。

作為總結,讓我們將一個簡單組件與一個類組件進行比較。

簡單組件
const SimpleComponent = () => {
  return <div>Example</div>
}
類組件
class ClassComponent extends Component {
  render() {
    return <div>Example</div>
  }
}

請注意,如果 return 包含在一行內,不需要括號。

道具

現在,我們有一個很酷的 Table 組件,但數據是硬編碼的。 React 的一大亮點是它如何處理數據,它使用屬性來處理數據,稱為 props , 並帶有狀態。現在,我們將專注於使用 props 處理數據。

首先,讓我們從 TableBody 中刪除所有數據 組件。

src/Table.js
const TableBody = () => {
  return <tbody />
}

然後讓我們將所有數據移動到一個對像數組中,就好像我們引入了一個基於 JSON 的 API。我們必須在 render() 中創建這個數組 .

src/App.js
class App extends Component {
  render() {
    const characters = [
      {
        name: 'Charlie',
        job: 'Janitor',
      },
      {
        name: 'Mac',
        job: 'Bouncer',
      },
      {
        name: 'Dee',
        job: 'Aspring actress',
      },
      {
        name: 'Dennis',
        job: 'Bartender',
      },
    ]

    return (
      <div className="container">
        <Table />
      </div>
    )
  }
}

現在,我們要將數據傳遞給子組件(Table ) 與屬性,你可以如何使用 data- 傳遞數據 屬性。我們可以隨心所欲地調用該屬性,只要它不是保留關鍵字,所以我將使用 characterData .我傳遞的數據是 characters 變量,我會在它周圍加上花括號,因為它是一個 JavaScript 表達式。

src/App.js
return (
  <div className="container">
    <Table characterData={characters} />
  </div>
)

現在數據正在傳遞到 Table ,我們必須努力從另一端訪問它。

src/Table.js
class Table extends Component {
  render() {
    const { characterData } = this.props

    return (
      <table>
        <TableHeader />
        <TableBody characterData={characterData} />
      </table>
    )
  }
}

如果你打開 React DevTools 並檢查 Table 組件,您將在屬性中看到數據數組。存儲在此處的數據稱為虛擬 DOM ,這是一種將數據與實際 DOM 同步的快速有效的方式。

不過,這些數據還沒有在實際的 DOM 中。在 Table ,我們可以通過this.props訪問所有的props .我們只通過一個道具,characterData,所以我們將使用 this.props.characterData 檢索該數據。

我將使用 ES6 屬性簡寫來創建一個包含 this.props.characterData 的變量 .

const { characterData } = this.props

由於我們的 Table 組件實際上由兩個較小的簡單組件組成,我將把它傳遞給 TableBody ,再次通過道具。

src/Table.js
class Table extends Component {
  render() {
    const { characterData } = this.props

    return (
      <table>
        <TableHeader />
        <TableBody characterData={characterData} />
      </table>
    )
  }
}

現在,TableBody 不帶參數並返回單個標籤。

src/Table.js
const TableBody = () => {
  return <tbody />
}

我們將 props 作為參數傳遞,並通過數組映射以返回數組中每個對象的表行。此地圖將包含在 rows 中 變量,我們將其作為表達式返回。

src/Table.js
const TableBody = (props) => {
  const rows = props.characterData.map((row, index) => {
    return (
      <tr key={index}>
        <td>{row.name}</td>
        <td>{row.job}</td>
      </tr>
    )
  })

  return <tbody>{rows}</tbody>
}

如果您查看應用程序的前端,現在正在加載所有數據。

您會注意到我為每個表行添加了一個鍵索引。在 React 中創建列表時,您應該始終使用鍵,因為它們有助於識別每個列表項。當我們想要操作列表項時,我們還將看到這是多麼必要。

Props 是將現有數據傳遞給 React 組件的有效方式,但是組件不能更改 props - 它們是只讀的。在下一節中,我們將學習如何使用狀態來進一步控制 React 中的數據處理。

狀態

現在,我們將字符數據存儲在一個變量中的數組中,並將其作為道具傳遞。這是一個很好的開始,但是想像一下我們是否希望能夠從數組中刪除一個項目。有了 props,我們就有了單向數據流,但是有了 state,我們可以更新組件的私有數據。

您可以將狀態視為應保存和修改的任何數據,而不必將其添加到數據庫中 - 例如,在確認購買之前從購物車中添加和刪除商品。

首先,我們將創建一個 state 對象。

src/App.js
class App extends Component {
  state = {}
}

該對象將包含您想要存儲在狀態中的所有內容的屬性。對我們來說,它是 characters .

src/App.js
class App extends Component {
  state = {
    characters: [],
  }
}

將我們之前創建的整個對像數組移動到 state.characters .

src/App.js
class App extends Component {
  state = {
    characters: [
      {
        name: 'Charlie',
        // the rest of the data
      },
    ],
  }
}

我們的數據正式包含在該州中。由於我們希望能夠從表格中刪除一個字符,我們將創建一個 removeCharacterApp 上的方法 類。

要檢索狀態,我們將獲得 this.state.characters 使用與以前相同的 ES6 方法。要更新狀態,我們將使用 this.setState() ,一種用於操作狀態的內置方法。我們將根據 index 過濾數組 我們通過,並返回新的數組。

src/App.js
removeCharacter = (index) => {
  const { characters } = this.state

  this.setState({
    characters: characters.filter((character, i) => {
      return i !== index
    }),
  })
}

filter 不會改變而是創建一個新數組,並且是在 JavaScript 中修改數組的首選方法。這種特殊的方法是測試一個索引與數組中的所有索引,並返回除了通過的索引之外的所有索引。

現在我們必須將該函數傳遞給組件,並在每個可以調用該函數的字符旁邊呈現一個按鈕。我們將傳遞 removeCharacter 作為 Table 的道具發揮作用 .

src/App.js
render() {
  const { characters } = this.state

  return (
    <div className="container">
      <Table characterData={characters} removeCharacter={this.removeCharacter} />
    </div>
  )
}

因為我們將它傳遞給 TableBody 來自 Table ,我們將不得不再次將它作為道具傳遞,就像我們對角色數據所做的那樣。

此外,因為事實證明我們項目中唯一擁有自己狀態的組件是 AppForm ,最好轉換 Table 從當前的類組件變成一個簡單的組件。

src/Table.js
const Table = (props) => {
  const { characterData, removeCharacter } = props

  return (
    <table>
      <TableHeader />
      <TableBody characterData={characterData} removeCharacter={removeCharacter} />
    </table>
  )
}

這是我們在 removeCharacter() 中定義的索引 方法進來。在TableBody 組件,我們將鍵/索引作為參數傳遞,因此過濾器函數知道要刪除哪個項目。我們將創建一個帶有 onClick 的按鈕 並通過它。

src/Table.js
<tr key={index}>
  <td>{row.name}</td>
  <td>{row.job}</td>
  <td>
    <button onClick={() => props.removeCharacter(index)}>Delete</button>
  </td>
</tr>

驚人的。現在我們有了刪除按鈕,我們可以通過刪除一個字符來修改我們的狀態。

我刪除了 Mac。

現在您應該了解狀態是如何初始化的以及如何修改它的。

提交表單數據

現在我們有數據存儲在狀態中,我們可以從狀態中刪除任何項目。但是,如果我們希望能夠向狀態添加新數據怎麼辦?在現實世界的應用程序中,您更有可能從空狀態開始並添加到它,例如使用待辦事項列表或購物車。

首先,讓我們從 state.characters 中刪除所有硬編碼數據 ,因為我們現在將通過表單對其進行更新。

src/App.js
class App extends Component {
  state = {
    characters: [],
  }
}

現在讓我們繼續創建一個 Form 組件在一個名為 Form.js 的新文件中 .

我們將設置 Form 的初始狀態 成為具有一些空屬性的對象,並將初始狀態分配給 this.state .

src/Form.js
import React, { Component } from 'react'

class Form extends Component {
  initialState = {
    name: '',
    job: '',
  }

  state = this.initialState
}

我們對這個表單的目標是更新 Form 的狀態 每次更改表單中的字段時,當我們提交時,所有數據都會傳遞給 App 狀態,然後將更新 Table .

首先,我們將創建每次對輸入進行更改時都會運行的函數。 event 將被傳遞,我們將設置 Form 的狀態 擁有 name (鍵)和 value 的輸入。

src/Form.js
handleChange = (event) => {
  const { name, value } = event.target

  this.setState({
    [name]: value,
  })
}

在繼續提交表單之前,讓我們先完成這項工作。在渲染中,讓我們從 state 中獲取我們的兩個屬性,並將它們分配為對應於正確表單鍵的值。我們將運行 handleChange() 方法為 onChange 輸入,最後我們將導出 Form 組件。

src/Form.js
render() {
  const { name, job } = this.state;

  return (
    <form>
      <label htmlFor="name">Name</label>
      <input
        type="text"
        name="name"
        id="name"
        value={name}
        onChange={this.handleChange} />
      <label htmlFor="job">Job</label>
      <input
        type="text"
        name="job"
        id="job"
        value={job}
        onChange={this.handleChange} />
    </form>
  );
}

export default Form;

App.js ,我們可以渲染表格下方的表格。

src/App.js
import Form from './Form'
src/App.js
return (
  <div className="container">
    <Table characterData={characters} removeCharacter={this.removeCharacter} />
    <Form />
  </div>
)

現在,如果我們轉到應用程序的前端,我們將看到一個還沒有提交的表單。更新一些字段,你會看到 Form 的本地狀態 正在更新中。

涼爽的。最後一步是允許我們實際提交該數據並更新父狀態。我們將創建一個名為 handleSubmit() 的函數 在 App 這將通過採用現有的 this.state.characters 來更新狀態 並添加新的 character 參數,使用 ES6 擴展運算符。

src/App.js
handleSubmit = (character) => {
  this.setState({ characters: [...this.state.characters, character] })
}

讓我們確保將其作為 Form 上的參數傳遞 .

<Form handleSubmit={this.handleSubmit} />

現在在 Form ,我們將創建一個名為 submitForm() 的方法 這將調用該函數,並傳遞 Form 狀態為 character 我們之前定義的參數。它還將狀態重置為初始狀態,以在提交後清除表單。

src/Form.js
submitForm = () => {
  this.props.handleSubmit(this.state)
  this.setState(this.initialState)
}

最後,我們將添加一個提交按鈕來提交表單。我們正在使用 onClick 而不是 onSubmit 因為我們沒有使用標準的提交功能。點擊會調用submitForm 我們剛剛製作。

<input type="button" value="Submit" onClick={this.submitForm} />

就是這樣!該應用程序已完成。我們可以從表中創建、添加和刪除用戶。自 TableTableBody 已經從狀態中拉出,它將正確顯示。

如果你在途中迷路了,可以在 GitHub 上查看完整的源代碼。

拉入 API 數據

React 的一個非常常見的用法是從 API 中提取數據。如果您不熟悉 API 是什麼或如何連接 API,我建議您閱讀如何使用 JavaScript 連接 API,它將引導您了解 API 是什麼以及如何將它們與 vanilla JavaScript 一起使用。

作為一個小測試,我們可以創建一個新的 Api.js 文件,並創建一個新的 App 在那裡。我們可以測試的公共 API 是 Wikipedia API,我在這裡有一個 URL 端點用於隨機*搜索。您可以轉到該鏈接查看 API - 並確保您的瀏覽器上安裝了 JSONView。

我們將使用 JavaScript 的內置 Fetch 從該 URL 端點收集數據並顯示它。您只需更改 index.js 中的 URL,即可在我們創建的應用程序和此測試文件之間切換 - import App from './Api'; .

我不會逐行解釋這段代碼,因為我們已經了解瞭如何通過狀態數組創建組件、渲染和映射。此代碼的新方面是 componentDidMount() ,一個 React 生命週期方法。 生命週期 是在 React 中調用方法的順序。 安裝 指的是插入到 DOM 中的項目。

當我們拉取 API 數據時,我們想使用 componentDidMount ,因為我們要確保在引入數據之前組件已經渲染到 DOM。在下面的代碼片段中,您將看到我們如何從 Wikipedia API 中引入數據,並將其顯示在頁面上

api.js
import React, { Component } from 'react'

class App extends Component {
  state = {
    data: [],
  }

  // Code is invoked after the component is mounted/inserted into the DOM tree.
  componentDidMount() {
    const url =
      'https://en.wikipedia.org/w/api.php?action=opensearch&search=Seona+Dancing&format=json&origin=*'

    fetch(url)
      .then((result) => result.json())
      .then((result) => {
        this.setState({
          data: result,
        })
      })
  }

  render() {
    const { data } = this.state

    const result = data.map((entry, index) => {
      return <li key={index}>{entry}</li>
    })

    return <ul>{result}</ul>
  }
}

export default App

在本地服務器中保存並運行此文件後,您將看到 DOM 中顯示的 Wikipedia API 數據。

還有其他生命週期方法,但對它們的介紹超出了本文的範圍。您可以在此處閱讀有關 React 組件的更多信息。

*維基百科搜索選擇可能不是隨機的。這可能是我在 2005 年率先發表的一篇文章。

構建和部署 React 應用

到目前為止,我們所做的一切都是在開發環境中進行的。我們一直在編譯、熱加載和即時更新。對於生產,我們將希望加載靜態文件 - 沒有源代碼。我們可以通過構建並部署它來做到這一點。

現在,如果您只想編譯所有 React 代碼並將其放在某個目錄的根目錄中,您只需運行以下行:

npm run build

這將創建一個 build 將包含您的應用程序的文件夾。把那個文件夾的內容放到任何地方,就大功告成了!

我們還可以更進一步,讓 npm 為我們部署。我們將構建到 GitHub 頁面,因此您必須熟悉 Git 並將您的代碼放到 GitHub 上。

確保您已退出本地 React 環境,因此代碼當前未運行。首先,我們要添加一個 homepage package.json 的字段 ,它有我們希望我們的應用程序存在的 URL。

包.json
"homepage": "https://taniarascia.github.io/react-tutorial",

我們還將這兩行添加到 scripts 屬性。

"scripts": {
  // ...
  "predeploy": "npm run build",
  "deploy": "gh-pages -d build"
}

在您的項目中,您將添加 gh-pages 到 devDependencies。

npm install --save-dev gh-pages

我們將創建 build ,其中將包含所有已編譯的靜態文件。

npm run build

最後,我們將部署到 gh-pages .

npm run deploy

我們完成了!該應用程序現已在 https://taniarascia.github.io/react-tutorial 上線。

結論

本文應該很好地介紹了 React、簡單和類組件、狀態、道具、處理表單數據、從 API 中提取數據以及部署應用程序。使用 React 學習和做的還有很多,但我希望你現在對自己鑽研和玩 React 有信心。

  • 在 GitHub 上查看源代碼
  • 查看項目

如果有任何不清楚的地方,或者您想在這篇文章或後續文章中看到什麼,請告訴我。


Tutorial JavaScript 教程
  1. Vue.js 中的另一個該死的 ToDo 應用

  2. 如何將 URL 參數轉換為 JavaScript 對象?

  3. Chrome:緩存存儲 VS 磁盤緩存

  4. 阻止 Internet Explorer 的默認圖像拖動操作

  5. Digger.dev:一種新型 PaaS

  6. 使用實用類型轉換 TypeScript 中的類型

  7. 原型繼承

  1. 跳入 React 或 Hooks

  2. JavaScript 刪除按鈕|示例代碼簡單

  3. 通天塔 <3 反應

  4. 在發布之前測試 npm 包

  5. 如何使用 Hooks 和 AG Grid 優化 React 應用程序

  6. 使用 styed-components 和 Material-UI withStyles 的 TextField 樣式

  7. 使用 Webpack 進行零配置 JavaScript 應用原型設計

  1. 使用 Kendo UI 創建動畫 React 組件

  2. 使用 Chrome DevTools 進行 JavaScript 調試

  3. 天才之路:卓越#57

  4. 21 個可供學習的 Vue.js 示例項目(開源,初級到中級)