原於 2023 年 4 月 2 日以簡單英文發佈於 Medium for JavaScript
在過去的幾周里,我開始學習 Web 開發世界中另一項備受追捧的技能:React.js。在我的一些導師的要求下,我對 JavaScript 中的許多東西至少感覺有點舒服,我認為這是實現我的職業目標最合乎邏輯的步驟。在這篇文章中,我將與大家分享一些我作為菜鳥時學到的東西。
在某些情況下,我只使用過 React 中的類別元件,從未使用過函數式元件。我不會在這裡描述它們之間的差異,因為我現在對函數式元件一無所知。有一天我可能會寫一篇文章來對比這兩種類型。即使在我寫這篇文章時,每個人都建議使用功能元件,但了解類別元件如何運作仍然是值得的,因為較舊的 React 專案可能會使用它們。
對於我的第一個項目,我的任務是建立一個債務計算器,用戶可以在其中輸入債務本金、利率以及他們想要支付的金額。這些輸入欄位有一些規定,但您可以在專案的 README.md 中閱讀這些規定(GitHub 儲存庫的連結位於文章末尾),或者您可以自己嘗試一下,看看它是如何運作的。用戶「提交」付款後,將出現付款記錄項目,提供有關本金、利息和餘額的詳細資訊。除非用戶在首次付款時還清了全部債務,否則在首次付款時除付款字段外的所有輸入字段均被禁用;如果還清全部債務,則整個表格將被禁用,並且用戶可以查看最終付款的歷史記錄記錄,以及一條表明他們沒有債務的消息。
我將回答我在開始學習 React 時遇到的以下問題:
什麼是 React.js,為什麼要使用它?
如何開始建立 React 應用程式?
典型的組件是什麼樣子?
如何在組件之間共用資訊?
我可以在 React 中有條件地渲染事物嗎?
如何部署 React 應用程式?
React 是一個前端 JS 函式庫(不是框架?)),它使組織大型專案變得更加容易。它最初是在 Facebook 開發的,當然,現在由 Meta 維護,Meta 也將它用於 Instagram。現在它廣泛應用於互聯網上的許多網站,例如 Airbnb、BBC、Imgur 和 Netflix 等。
React 程式碼由可重複使用的元件組成,這些元件必須位於 src 資料夾內,且其名稱必須採用 CamelCase 形式。許多元件都是用 JSX(JavaScript 語法擴充功能)編寫的,這是 HTML 和 JS 的混合。我稱這些組件為“可重複使用”,因為它們具有相同的結構,並且可以將不同的資訊傳遞給它們並顯示在網站上。元件也可以用普通的 JS 來寫。然後可以將不同的資訊(例如使用者帳戶資訊)傳遞給這些元件,並且它們都將以相同的方式顯示。
要初始化 React 應用程序,請在終端機中輸入以下命令:
npx create-react-app project-name cd project-name npm start
npm start 將在預設瀏覽器的空連接埠中開啟項目。
通常需要幾分鐘的時間才能完成所有設置,因此可以同時做一些富有成效的事情,例如將愚蠢的舞蹈上傳到TikTok,或者找出您將被分入哪個霍格沃茨學院(是的,我做了那個測驗)。
官方文件現在建議使用框架來初始化React應用程式。我還沒有使用過,但你可以在這裡閱讀更多相關資訊。
就像我提到的,到目前為止我只使用過類別元件,所以我只會在本文中介紹這些元件。我在第一個專案中使用的元件放在這裡有點大,因此請參閱本文末尾連結的儲存庫中 src 資料夾中的 App.js 和 PaymentHistory.jsx 檔案以查看它們的實際情況。儘管如此,典型的類別組件可能如下所示:
// Import React & ComponentOne: import React from "react"; import ComponentOne from "./ComponentOne; class App extends React.Component { /* Add props as params here, in case state values are to be shared with another component */ constructor(props) { super(props); // Initialize state values: this.state = { stateValue1: '', stateValue2: '' } } // Add some methods: changeFontColor = () => { // do something } changeFont= () => { // do something } // Determine what the component should render: render() { return ( <div> <p key="pgHeader" onClick={this.changeFontColor}>Header</p> <p key="pgContent" onClick={this.changeFont}>Content</p> <p key="pgFooter">Footer</p> </div> // Give ComponentOne access to method changeFont by passing it in as a prop: <ComponentOne changeFont={this.changeFont} /> ) } } export default App;
請注意,我為每個
新增了一個鍵值
像普通的 JS Class 一樣,首先應該是 constructor(),然後是 super()。例如,如果我們希望將狀態值或方法從一個類別共用到另一個類,我們需要傳入 props(「properties」的縮寫)作為 constructor() 和 super() 的參數。
然後,我們應該初始化狀態值。在我的債務計算器專案中,我需要使用多個狀態值來追蹤與付款、本金、所欠利息和餘額相關的各種金額,但我還使用了一些狀態值來確定如何或是否應呈現某些內容。以下是我如何使用 isDebtFree 狀態值在等於 false 時啟用輸入字段,並在等於 true 時停用它:
npx create-react-app project-name cd project-name npm start
如您所見,我們可以使用 setState 函數更改類組件中的狀態值。請記住,setState 是異步運行的,因此任何需要更新狀態值的功能都可以放入回調中。但是,您應該使這些回調盡可能簡單,否則您將最終陷入“回調地獄”的混亂世界,因此在組件中創建方法時請盡可能遵循單一職責原則。您還應該知道,每次組件內的狀態發生更改時,組件都會重新渲染。
不應在方法內部直接操作 DOM。這樣做被稱為“反模式”。請注意,我沒有通過在方法內設置禁用屬性來直接訪問 DOM 元素,如下所示:
// Import React & ComponentOne: import React from "react"; import ComponentOne from "./ComponentOne; class App extends React.Component { /* Add props as params here, in case state values are to be shared with another component */ constructor(props) { super(props); // Initialize state values: this.state = { stateValue1: '', stateValue2: '' } } // Add some methods: changeFontColor = () => { // do something } changeFont= () => { // do something } // Determine what the component should render: render() { return ( <div> <p key="pgHeader" onClick={this.changeFontColor}>Header</p> <p key="pgContent" onClick={this.changeFont}>Content</p> <p key="pgFooter">Footer</p> </div> // Give ComponentOne access to method changeFont by passing it in as a prop: <ComponentOne changeFont={this.changeFont} /> ) } } export default App;
相反,return() 中的部分HTML 元素應該設置為一個狀態值,該狀態值可能會根據組件中方法的執行而發生變化,正如我在本段正上方代碼塊之前的代碼塊中向您展示的那樣。
還要注意的一點是組件的 return() 表達式應盡可能短,因此避免在那裡放置任何類型的數學表達式以及此處定義的功能。起初,當我嘗試在付款字段中設置最小和最大值時,我犯了這個錯誤,這些值根據狀態值而變化,當數字輸入本金和利率字段以及付款時,狀態值會發生變化。
我為每個值創建了一個方法,然後將最小值和最大值設置為這些方法返回的值。下面的第一種方法有效,但在 React 中這並不是一個好方法,因為組件的 return() 部分應該盡可能短且易於閱讀。
// Initialize isDebtFree: // Should go inside the constructor, but left out here for brevity this.state = { // other state values isDebtFree: false // other state values } // Change isDebtFree to true if payment equals the total remaining balance // This method will be called upon payment submission updateValues = () => { // other stuff if (newBalance === 0) { this.setState({ isDebtFree: true }) } } // Set the disabled property of an input field to equal isDebtFree: render() { return ( <input disabled={this.state.isDebtFree} /> ) }
下面的方法更符合React精神:
// DO NOT ACCESS DOM ELEMENTS DIRECTLY INSIDE A METHOD! updateValues = () => { if (newBalance === 0) { document.getElementById('payment').disabled = true; } }
正如您在本文的第一個編碼塊中看到的,我使用 props 將一個方法從一個組件傳遞到另一個組件。現在,讓我們看看第二個組件如何訪問我們在上面第一個代碼塊中從 App 傳遞給它的內容。這就是該部分的樣子,以防您懶得一直向上滾動來查看它:
// You could put math operations directly inside elements in return()... // ... but this is not the best way render() { return ( <input type="number" min={ this.state.principal / 100 + (this.state.principal * Number(this.state.interestRate)) / 100 / 12; } max = { this.state.principal + (this.state.principal * Number(this.state.interestRate)) / 100 / 12; } /> ) }
現在,在 ComponentOne 中,讓我們從 App 導入此方法並使用它:
// A BETTER WAY // Create 2 methods; one returns the min payment possible, the other the max: getMinPmt = () => { let minPmt = this.cleanValue(this.state.principal / 100) + this.cleanValue( (this.state.principal * Number(this.state.interestRate)) / 100 / 12 ); let totalBalance = this.state.principal + this.cleanValue( (this.state.principal * Number(this.state.interestRate)) / 100 / 12 ); if (totalBalance <= 100 && totalBalance > 0) { minPmt = totalBalance; } return this.cleanValue(minPmt); }; getMaxPmt = () => { let maxPmt = this.state.principal + this.cleanValue( (this.state.principal * Number(this.state.interestRate)) / 100 / 12 ); return this.cleanValue(maxPmt); }; // Set the min & max values of the input to what the respective method returns: render() { return ( <input type="number" min={this.getMinPmt()} max={this.getMaxPmt()} /> ) }
因此,訪問changeFont方法後,我們在單擊渲染的h1時調用它。
是的! React就是有條件地渲染事物。有幾種方法可以做到。您可以使用一種方法來執行此操作,然後將元素的值設置為return()中的元素值。因此,讓我們再次使用債務計算器示例。假設我們想顯示“您沒有債務!”的信息。如果餘額的狀態值為0,並且如果餘額超過0,則提示用戶另一種付款的按鈕。我們可以通過幾種方式來執行此操作。
>讓我們首先根據條件將該元素的值設置為方法返回的內容:
npx create-react-app project-name cd project-name npm start
使用一種方法可能是有利的,因為它允許我們更簡潔。我們還可以添加更複雜的條件,就像在正常的JS函數中一樣。
我們還可以在return()內部使用三元運算符來完成相同的事情:
// Import React & ComponentOne: import React from "react"; import ComponentOne from "./ComponentOne; class App extends React.Component { /* Add props as params here, in case state values are to be shared with another component */ constructor(props) { super(props); // Initialize state values: this.state = { stateValue1: '', stateValue2: '' } } // Add some methods: changeFontColor = () => { // do something } changeFont= () => { // do something } // Determine what the component should render: render() { return ( <div> <p key="pgHeader" onClick={this.changeFontColor}>Header</p> <p key="pgContent" onClick={this.changeFont}>Content</p> <p key="pgFooter">Footer</p> </div> // Give ComponentOne access to method changeFont by passing it in as a prop: <ComponentOne changeFont={this.changeFont} /> ) } } export default App;
如果this.state.totalbalance嚴格等於0,則該消息將顯示。如果沒有,那麼什麼都不會顯示。
// Initialize isDebtFree: // Should go inside the constructor, but left out here for brevity this.state = { // other state values isDebtFree: false // other state values } // Change isDebtFree to true if payment equals the total remaining balance // This method will be called upon payment submission updateValues = () => { // other stuff if (newBalance === 0) { this.setState({ isDebtFree: true }) } } // Set the disabled property of an input field to equal isDebtFree: render() { return ( <input disabled={this.state.isDebtFree} /> ) }
>我通過Netlify部署了我的第一個React項目,我授予該項目訪問該項目的GitHub存儲庫。在部署之前,您應該運行NPM運行構建,以構建為構建文件夾生產的應用程序。它捆綁在生產模式下反應,並優化構建以獲得最佳性能。您可以像往常一樣更新網站。
>
>因此,在構建第一個React項目時,我學到了一些東西。我對React的了解還不能深入,因此,如果您對我有任何建議或要添加的任何信息,請添加評論。如果您發現它有幫助,請發表好評論或留下某種反應,如果您認為其他人可以從閱讀本文中受益,請將其傳遞給他們。
> 感謝您的閱讀!
我的第一個項目
Project的GitHub存儲庫
以上是React.js:我從第一個專案中學到了什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!