React 簡介,第 1 部分

已發表: 2020-07-02

我們已經在這個博客中談到了 WordPress 的新開發堆棧以及隨之而來的革命,無論是對於平臺本身還是對於現在被迫學習新東西的開發人員。 例如,不久前,我發表了一篇文章,解釋瞭如何使用@wordpress/scripts包來擴展 Gutenberg 並在其 UI 中添加一個按鈕。 作為一名作者,我喜歡寫教程,因為我可以分享我熟悉的東西,而且我覺得我們可以一起學習。

不幸的是,我認為教程隱藏了一個大問題:你們中的許多人盲目地遵循它們而沒有真正理解發生了什麼,即使你最終得到了正確的結果。 但是大多數教程都缺乏“啊哈時刻”,即洞察力和理解力的時刻,在這種時刻,一切都在你的腦海中響起,你就會明白事情為什麼會這樣。

所以今天我想開始一系列的文章,介紹 React 來闡明一點點。 我想揭開 React 的神秘面紗,並幫助你快速掌握它。 我想讓你理解為什麼 React 是這樣的,以及為什麼事情是這樣的。 我希望你了解 React 背後的原則。 我希望你寫出更好的代碼。

函數式編程

在談論 React 之前,我認為值得花幾分鐘談論函數式編程,因為我們今天使用的許多框架都依賴於它的原則。 React(連同 Redux)也不例外。

函數式編程是一種編程範式,其中通過應用和組合函數來構建程序。 你可能會想,嗯,“編程”一直都是關於構建和運行函數的,對吧? 不完全是。 忍受我。

例如,考慮面向對象的編程。 在 OOP 中,程序是通過創建和組合對象來構建的,對象可以包含屬性或字段形式的數據,以及方法或過程形式的代碼。 看? 不是函數,而是對象。

那麼函數式編程有什麼特別之處呢? 嗯,函數式編程有幾個方面的特點:純函數、引用透明性、不變性、作為一階公民的函數、高階函數等,我建議你自己研究它們(或者,如果你想要我到,我們可以在以後的帖子中討論它們)。 但是,為了保持這篇文章的簡短,今天我們將只關註一個功能......

純函數

使函數式編程與其他編程範式不同的一件事是它如何定義和使用函數。 在 FP 中,函數是純函數,這意味著它們滿足以下兩個條件:

  1. 當給定相同的參數時,它總是產生相同的結果
  2. 它沒有副作用

例如,這不是一個純函數:

 let previousName = 'David'; function greet( name ) { if ( previousName !== name ) { console.log( `Hello, ${ name }!` ); } else { console.log( `Welcome back, ${ name }!` ); } previousName = name; }

因為它有幾個副作用。 也就是說,它修改了一個全局變量(副作用 1)並將一些文本輸出到控制台(副作用 2)。

另一個不純函數如下:

 function createElement( name ) { const id = Math.random(); return { id, name }; }

因為,如您所見,它並不總是產生相同的結果。 每次使用某個名稱調用createElement時,他們得到的結果都是不同的。 畢竟id屬性是通過Math.random生成的……

純函數之所以偉大,原因有很多:它們易於理解並且沒有任何意外。 你給他們一些輸入,他們會給你一個特定的輸出。 這很棒,因為這種定義函數的方式使它們更接近於我們對函數是什麼的數學理解:它將每個輸入映射到一個明確定義的輸出。

React 中的組件

純函數和函數式編程要做什麼? 好吧,讓我們看看我們是否可以推導出他們的關係......

正如您在其文檔中所讀到的,React 是一個 JavaScript 庫,用於通過稱為“組件”的小段代碼創建用戶界面。 這是您將在他們的教程中看到的第一個組件:

 class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Shopping List for { this.props.name }</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } }

很簡單,甚至不言自明,不是嗎?

但是等一下! 這看起來一點也不像“純函數”。 事實上,這是一個使用面向對象編程實現的類。

做一個古怪鬼臉的女人的 Gif

是的,你完全正確。 這看起來不太好……我們只是在浪費時間談論函數式編程嗎?

再看一下前面的組件。 它是什麼樣子的? 它有什麼作用? 嗯,它是一個具有單個方法 ( render ) 的類,它生成一些 HTML 來呈現購物清單。 這個購物清單總是一樣的(呃,這是一個簡單的例子),但它有一個可變部分:它的標題,這個類似乎使用了一個內部屬性this.props.name

因此,如果我們對 React 還一無所知,並且只查看代碼並嘗試推斷它的作用,我們會看到以下內容:

  1. 該組件可以接收一個“名稱”。 我們不確切知道它是如何得這個名字的,但我們知道它確實如此。 畢竟this.props.name是一個很好的線索。
  2. render方法生成一些 HTML 來呈現“購物元素”的(靜態)列表: InstagramWhatsAppOculus
  3. 生成的 HTML 不是 100% 靜態的; 它使用的“名稱”可以根據屬性的值而變化。

看看我要去哪裡?

React 中的組件函數

我們只是描述了一個純函數! 我們有一個組件,它接受一個值( name )並產生一個定義良好的輸出(HTML)。 這是否意味著我們可以擺脫 OOP 並將之前的組件實現為函數?

Gif 顯示一個男人懷疑自己在想什麼

當然! 我們剛剛看到的過於復雜的類可以重寫為一個更簡單、更容易理解的純函數,它接收props並返回 HTML:

 const ShoppingList = ( props ) => ( <div className="shopping-list"> <h1>Shopping List for { props.name }</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> );

這與我們所擁有的完全相同,但方式更簡單。 我什至敢說這是我作為程序員可以實現的最簡單的東西: React 組件只不過是一個函數,它接收一些 props 並生成一個 HTML out

這正是你必須學習的第一課:你的 React 組件是一個純函數:props in,HTML out。 組件不得執行異步函數來獲取數據(因為這些是副作用)。 組件也不能修改它接收到的屬性(不變性)。

所以,再來一次:一個組件只是簡單地接受一些 props 並產生 HTML 輸出。 時期。

但是等等,如果一個組件這麼簡單,我們怎麼能用它們做任何有用的事情呢? 好吧,請繼續關注,因為我們將在下一篇文章中討論這個!

Josiah Weiss 在 Unsplash 上的精選圖片。