React入門級小白指北及常見問題解答
原文作者:IMWeb 魔
原文鏈接:React入門級小白指北及常見問題解答 - 騰訊Web前端 IMWeb 團隊社區
1.前言
最近學習使用 React 開發課程項目,作為剛接觸React的新人,其中遇到一些解決方式很簡答,但卻也需要花時間去尋找答案的問題。本著為新人節約時間的目的,才有了這篇文章。注釋,此樣式文字說明其內容引用自官方文檔內容。
2.合理定義組件 state
古語云,知其然知其所以然。在正式使用 React 前,理解其設計理念對於開發應用是十分有必要的,先來看看 React 的一些理念。
React 的眾多優點之一是它讓你在編寫代碼的時候同時也在思考你的應用。
React 官方文檔的這句話,在應用拆分為組件,以及設計組件state的這個過程中體現的淋漓盡致。使用 React 開發應用的過程,也是不斷在思考如何搭建應用的過程。
為了正確構建你的應用,首先你需要考慮你的應用所需要的最小可變狀態集。
對於這句話的,我的理解是:組件中的 state 數據是用於記錄組件當前交互的結果,而且 state 所記錄的數據,應當做到既滿足需求又不多餘。那麼如何去做到這些?官方文檔中也給出了標準,即三個問題:
1.它是通過 props 從父級傳來的嗎?如果是,它可能不是 state。
2.它隨著時間推移不變嗎?如果是,它可能不是 state。
3.你能夠根據組件中任何其他的 state 或 props 把它計算出來嗎?如果是,它不是 state。
問題一很好理解,數據如果可以從父級組件那裡拿到,那麼就可以在 render 中現拿現用,沒必要再設置一個多餘的 state。
問題二也很簡單,但是我認為會是新人最容易犯錯誤的一點,包括我自己。如果組件里有一個定值,那麼完全可以通過正常的定義變數去記錄,而不是把 state 當作變數去使用。
問題三與問題一類似,如果某個數據能從其它組件那裡傳遞過來的數據計算得來,那麼也沒必要設置成 state。簡單來說,知道了矩形的長與寬,那麼面積自然就可以求出來,沒必要再用一個 state 去記錄矩形面積。 除了官方給出的三點之外,我認為還有標籤的某些交互屬性也不應設置為 state。比如結合 CSS 的屬性選擇器來控制標籤的隱藏與顯示,標籤不會自發的去隱藏或顯示,它肯定是交互的結果,那麼依然可以從別的組件那裡拿到數據來控制樣式。 引用文檔點此傳送
3.setState
setState方法設置數據是非同步的!
setState方法設置數據是非同步的!!
setState方法設置數據是非同步的!!!
最初使用React的時候並不知道這個點,導致代碼邏輯沒有錯誤,但拿到的數據始終是unfinded。後來找了文檔才知道原因是setState非同步設置數據,那麼自然下一條語句讀取數據時是unfinded。 因為 this.props 和 this.state 可能是非同步更新的,你不應該依靠它們的值來計算下一個狀態。
非同步數據何時能正確設置是不確定的,那麼自然根據它來計算下一個值也是不確定的,所以在代碼里使用 state 數據時,做數據檢驗是十分必要的。不過好在 setState 方法可以擁有一個回調函數,當數據設置完畢後,就調用這個函數,寫法如下:
第一個參數是 state 對象屬性的設置,第二個參數是回調函數,使用了 ES6 箭頭函數的語法,關於 state 更多知識的 官方文檔點這裡。
推薦另一篇深入介紹 state 的文章,點擊傳送。
4.狀態提升與單向數據流
使用 react 經常會遇到幾個組件需要共用狀態數據的情況。這種情況下,我們最好將這部分共享的狀態提升至他們最近的父組件當中進行管理。根據上文設計 state 數據的原則,state 數據應當做到最小可變狀態集,那麼如果某個狀態數據是幾個組件都需要且相同的,那麼分別設置在組件中顯然不合適,顯得冗餘。這時候最佳的方式就是將這些共用的state數據提升至離需要這些數據的組件最近的父組件來完成,這就是所謂的狀態提升。
既然共享的狀態數據都會提升至它們最近的父組件當中,那麼當其子組件需要數據時,都會從它們的父組件里去拿。這樣數據就是從一個父組件流向多個子組件,也就是單向數據流。在React應用中,對應任何可變數據理應只有一個單一「數據源」。……你應該在應用中保持自上而下的數據流,而不是嘗試在不同組件中同步狀態。這樣的數據流像瀑布一樣,最高層有一個唯一的源頭,從上至下傳輸數據到每個組件。而這樣做的好處則是你也可以更快地尋找和定位bug的工作。因為哪個組件保存有狀態數據,也只有它自己能夠操作這些數據,發生bug的範圍就被大大地減小了。
至此,React三個重要的理念就介紹完了,再回到開始的那句話它讓你在編寫代碼的時候同時也在思考你的應用。不管是在應用開發前的分析數據流,拆分模塊,還是開發過程中不斷凝練、簡化state,組件更細緻化。React都要求你要去不斷思考自己的應用,如何讓應用的思路更清晰,更具模塊性。
5.React中常見功能的實現
5.1 本地圖片的引用
要使用本地圖片,首先得安裝兩個npm包: url-loader,詳情點擊 file-loader,詳情點擊 理論上來說url-loader封裝了file-loader,只需要安裝url-loader即可。但在實際使用中 Chrome 調試里還是看到了關於file-loader的錯誤,於是我兩者都安裝了,使用方法如下。 webpack.config.js文件配置,如圖:
組件中引用方式,如圖:
更多關於圖片的使用,以及參數的詳解,可以參考這篇文章,點擊傳送。
5.2 滾動事件的綁定
只需在內容超出的標籤上使用 overflow: scroll 樣式即可出現滾動條,但滾動事件的綁定,讓我費了一些時間。在網上找到一種使用 window.addEventListener 監聽滾動事件的辦法,可我沒有試成功,望知道的朋友告知下。於是我使用另一種方法,組件代碼如下:
這裡要說明的是 ref 屬性的用法,可以在函數里使用 console.log(this) 將組件對象輸出到控制台,展開返回的對象屬性就能看到添加了 ref 屬性的標籤全都在 refs 屬性里。根據屬性路徑讀取它,就能返回這個標籤實例。我自己的理解是,它就像 DOM 里的document.getElementById(id)方法一樣,只是把標籤的 id 屬性換成了 ref 屬性。
5.3 map遍歷對象數組錯誤
在使用map函數(array.map(function(currentValue, index, arr), thisValue))遍歷對象數組生成 li 列表時,有時會出現如下錯誤:
原因是這時 currentValue 傳遞的是一個對象(Object),而不是一個數值(String, Nubmer等等),因此才會提示在這個對象中還找到了相關的鍵值。所以,如果遍歷的數組是[1, 2, 3, 4……]這樣的結構的,currentValue傳遞的是數值,會正常渲染。而遍歷的數組是[{name: a}, {name: b}, {name: c}……]這樣的對象集合,則會有錯誤提示發現還有name這個鍵值。不過可以通過 currentValue.name 這樣寫來獲得數值,也是可以通過的。
有一點例外就是 currentValue 作為 props 傳遞給 React 自定義組件的話,即使是對象(Object)也是可以的。
前端NEXT學位課程第六期正在招生中!感興趣的小夥伴快點擊這裡,了解課程詳情吧!
更多乾貨與福利請關注公眾號【騰訊NEXT學位】!
推薦閱讀:
※Hexo博客搭建(一)前期準備
※大齡電力汪前端學習路(頁面渲染篇)
※飢人谷的「教練模式」是什麼?
※格物致知——一個程序老鳥的對人生的一些感慨和總結!
※Hexo博客搭建(三)上線與域名設置