React 生態系統:從小白到大神

2021-02-26 GitBook社區

本文來自作者 Yeh. 在 GitChat 上精彩分享,  「閱讀原文」看看大家與作者交流了哪些問題

【不要錯過文末彩蛋】

編輯 | 汶澤

引言

要了解 React 的思想,還得從下面這張圖說起。


The State-Action-Model (SAM) Pattern

話說2016年2月的一篇文章 no-more-mvc-frameworks 描述了一種新的函數式、響應式模型,而它的思想來源正是來自 React 和 TLA+,這一模型就叫做 SAM 模型。

SAM 模型讓前端開發人員更專注於從模型中去建立視圖,而不會受牽制於基礎 API。

因此 SAM 完全符合軟體架構的重要設計原則。這種模型的最佳實踐莫過於 React 與 Angular 了,隨著他們的發展,前端架構思想開始了轉變。

雖然 React 官網將 React 定位為創建用戶界面的JS庫,但我想說的是,「React is just the View in MVC」這一說法太過委婉了。

React 所帶來的是整個前端技術棧的進化,各種函數響應式框架逐漸在完善。隨著 React 的發展和流行,圍繞著 React 的生態系統已經逐漸形成。

而從 React 小白到大神,必須要經歷三個境界,但總歸起來就五個字:「就解問題嘛」——出自「阿里掃地僧」多隆。

因此,本文通過描述每個知識點解決了哪些問題的方式來為大家介紹 React生態系統。

一、React龐大的體系1.1 ReactJS

ReactJS 到底解決了哪些問題呢?先來一份總結的 ReactJS 特點:

高效:React 通過虛擬 DOM 和 Diff 算法,最大限度地減少與DOM的交互和渲染。——提高運行效率

組件化:通過 React 構建組件,使得代碼更加容易復用,適應大型項目開發。——提高可維護性和復用性以及開發效率

模塊化:通過模塊化工具庫來解決模塊化問題——提高可維護性和復用性

單向數據流:React 實現了單向響應的數據流,從而減少了重複代碼,這也是它為什麼比傳統數據綁定更簡單。提高可維護性。

一言以蔽之,ReactJS 解決了前端技術規劃中應該考慮的這幾件事:組件化、模塊化、開發效率、運行效率、可維護性…

1.2 React生命周期

下圖很直觀地描述了 React 生命周期的整個過程:

React生命周期

這裡有個不錯的 github 項目:react-pxq。這是的一個 react + redux 項目,其中滲透出了作者(bailicangdu)對 react 的理解,能很好的幫助大家快速上手 react。

生命周期這東西說簡單也簡單,說難也難。有的人說,不就是幾個階段嗎?

但如果你是去面試,有經驗的面試官可能會出這樣幾道題:

React 在初始化和更新的時候會觸發的鉤子函數?

父組件在更新狀態的時候父組件與子組件的生命周期順序是怎麼執行的?

針對第1個問題,就算不懂的人看幾眼背一下都能答出來。而第2個問題就比較考驗你的知識深度了。

首先需要知道子組件在什麼時候會被渲染?它一定會被渲染嗎?有什麼方法能夠減少它的渲染?一大堆引申的知識點,如果能應對如流(最好的方法是看源碼咯),相信你會給面試官留下好印象。

1.3 React Router

React Router 是 React 中使用的路由庫,通過管理URL來管理組件及對應的狀態。

Router 組件本身只是一個容器,真正的路由要通過 Route 組件定義。

Router 組件支持嵌套路由、支持通配符,能讓你輕鬆控制整個項目的路由結構。

1.4 Redux

Redux 跟 React 沒有直接的關係,本身可以支持 React、Angular、Ember等等框架。Redux 其實是 Flux-like 更優雅的寫法,下圖對比了Flux與Redux的數據流向:


Flux與Redux的數據流向

通過 react-redux 這個庫,可以方便的將 react 和 redux 結合起來:React負責頁面展現,Redux 負責維護/更新數據狀態。

大致過程為:當用戶在 View 中觸發事件產生 Action,Action 進到 Reducer,Reducer 根據 Action Type 去匹配對應處理的動作,然後返回一個新的狀態。

View 則因為檢測到狀態更新而進行重繪。Redux 只有一個 Store 負責存放整個 App 的狀態,而唯一能改變狀態的方法只有發送 Action。

Redux 社區中使用比較多的庫有:redux-sagas、redux-gen、redux-loop、redux-effects、redux-side-effects、redux-thunks、rx-redux、redux-rx…

1.5 React測試

目前廣大開發者偏向使用 Airbnb 團隊開發的 enzyme,它也可以與其他測試工具如 Jest、Mocha 等配合使用。

比如我們使用 jest-enzyme,由於Jest是 Facebook 開發並且是在 Jasmine 測試框架上演變而來的,斷言格式我們比較熟悉,因此大家可能更容易上手。

Jest 的目標是減少測試一個項目所要花費的時間和認知負荷,它提供了大部分我們需要的現成工具:快速的命令行接口、Mock 工具集以及它的自動模塊 Mock 系統,總的來說就是讓測試變得更簡單。

1.6 React Native

RN 是在 Facebook 所提出的核心概念 Learn once, write anywhere 所誕生的產物,著力於提高多平臺開發的開發效率。

我們可以同時為 android 和 ios 兩個平臺開發 App,只需要根據兩個平臺不一樣的地方去做一些調整即可。

RN 主要負責 UI 部分,而原生主要負責交互和數據處理。RN 屬於 hybrid 開發,並且與原生無縫連接,相比 Web App 和 Native 開發,RN取長補短,集合了兩者的優勢。

RN 開發的 APP 可以跳過 App Store 審核,遠程更新代碼,提高迭代頻率和效率,既有 Native 的體驗,又保留 React 的開發效率。

RN 的原理是將 React 代碼轉化為原生 API,iOS 一套,Android 一套。RN在一開始生成OC模塊表,然後把這個模塊表傳入JS中,JS參照模塊表,就能間接調用OC的代碼。

相當於買了一個產品(OC),對應一份說明書(模塊表),用戶(JS)參照說明書去操作這個產品。

如何學習RN呢?可以跟著 git 上的 awesome 系列去進階。從源碼角度看RN,主要需要了解RN如何做到JS和OC交互、RN的啟動流程是怎樣的、如何加載 JS 源碼、UI 控制項的渲染流程、事件處理流程以及 RN 與 iOS 之間的通信方式等。

做 React 還需要懂什麼?

1.7 Node

Node 打破了過去JS只能在瀏覽器中運行的局面。前後端編程環境的統一,大大降低了前後端轉換所需要的上下文交換代價。

Node 就是瀏覽器在協議棧另一邊的倒影,雖然不處理UI,卻與瀏覽器有著相同的機制和運行原理。其高性能並行 I/O 使得分布式開發更加高效,利用穩定接口可提升 web 渲染速度,也十分適合做實時應用開發。

第2部分將闡述 Node 在前後端中的角色作用。

1.8 NPM與Yarn

我們知道 Node 的包描述文件是一個 JSON 文件,用於描述非代碼相關的信息。而 NPM 則是一個根據包規範來提供 Node 服務的 Node 包管理器。它解決了依賴包安裝的問題,卻面臨著兩個新的問題:

安裝的時候無法保證速度和一致性。

安全問題,因為NPM安裝時允許運行代碼。

於是 Yarn 就出現了,不要慌,它並沒有試圖完全取 NPM,不過 Yarn 確實也是可以完美替代 npm 的。

1.9 模塊化開發

隨著 web 應用的發展,前端的業務邏輯越來越複雜,代碼也越來越多,各種問題就暴露出來了:全局變量汙染、函數命名衝突、依賴關係混亂等問題嚴重阻礙了前端開發的發展,JS模塊化勢在必行。通過開發者不斷地嘗試,出現了各種規範和實踐:

CommonJS

Node.JS 首先採用了js模塊化的概念。Node.js 伺服器端通過 exports、module.exports 來輸出模塊,並使用 require 同步載入模塊,而瀏覽器端的可以使用 Browserify 實現。

AMD

AMD規範用於異步加載模塊,主要用於瀏覽器端,當然也支持其他js環境,主要應用有requireJS。

ES6 Module

ES6 標準定義了JS的模塊化方式,目的是取代 CommonJS、AMD、CMD 等規範,一統江湖,成為通用的模塊化解決方案。

但瀏覽器和Node端對ES6的支持度還不是很高,需要用 Babel 進行轉譯(Babel編譯器可以將ES6、JSX等代碼轉換成瀏覽器可以看得懂的語法)。

Gulp/Grunt+Webpack/Browserify

在構建前端項目資源,使用自動化工具協助進行自動化程序碼打包、轉譯等重複性工作,可以大幅提升開發效率。

Gulp

Gulp和Grunt一樣是一種基於任務的構建工具,能夠優化前端工作流程。

Webpack

webpack 傻瓜式的項目構建方式解決了模塊化開發和靜態文件處理兩大問題。但隨著項目越來越大,特定需求的出現就使得 webpack 越來越難配置了。

因此 webpack 在沒太多特定需求的項目使用是沒有問題的,當然,webpack 的未來肯定是圍繞ES的支持度、構建速度與產出代碼的性能和用戶體驗來建設的。其未來的重要關注點:

高性能的構建緩存

提升初始化速度和增量構建效率

更好的支持Type Script

修訂長期緩存

支持WASM模塊支持

提升用戶體驗

Browserify

Browserify是基於Unix小工具協作的方式實現模塊化方案的,輕便且配置容易,管道形式的組織則讓開發者很容易插拔或修改其中某一環節的操作。

至於怎麼配合使用,我覺得仁者見仁智者見智,確實是不好下定論,只有親身體驗才能擇更好者而用吧。

ES2015/ES6

我們都知道ECMASCRIPT是組成JS的三要素之一,ES6其第6個版本,ES的歷史確實也挺曲折的。通過ES6最常用的特性,我們來了解ES6到底解決了什麼:

let, const(變量類型):解決變量作用域洩露的問題。

Class, extends, super(類、繼承):讓對象原型的寫法更加清晰、更像面向對象編程的語法,也更加通俗易懂。

Arrow functions(箭頭函數):1.簡潔、簡潔、簡潔,2.解決this綁定的問題(繼承外面的this)。

Template string(模板字符串):解決傳統寫法非常麻煩的問題。

Destructuring(解構):避免讓API使用者記住多個參數的使用順序。

Default, rest(默認值、參數):簡化,替代arguments,使代碼更易於閱讀。

ImmutableJS

我們知道在 JavaScript 中有兩種數據類型:基礎數據類型和引用類型。在 JavaScript 中的對象數據是可以變的,由於使用了引用,所以修改了複製的值也會相應地修改原始值。

通常我們用 deepCopy 來避免修改,但這樣做法會產生資源浪費。而 ImmutableJS 的出現很好的解決了這一問題。

React的生態系統還有噓噓多多相關的知識,本文並不能全面涵蓋所有知識,望諒解。

另外,推薦大家從 git 上的 awesome 系列去學習你想要學習的一門知識。

如果是有英文而沒有中文,大家也可以fork下來去做一些翻譯,為大前端技術做做貢獻嘛!:-D

二、前後端架構分離

前後端分離的分層架構圖

很多人都有過 MVC 架構的開發經驗,從 Spring MVC 開始,寫JSP,再到使用 freemarker,然後再到狹義的前後端分離,也就是 Web 端通過ajax調用接口,使用JS把數據渲染到頁面上。

以前後端人員套頁面,數據結構和業務邏輯混淆在一起,項目越來越大後,維護起來特別的繁瑣。

目前看到的前後端分離項目都是上圖所示這種形式去實現的。尤其是在大公司,基本都是採用面向服務架構的開發模式,團隊開發中的溝通成本以及職責明確特別重要。

而前後端分離的意義主要在於解耦,解耦後前後端職責劃分更明確,前端能做的事也越來越多。

比如我們可以在 Node 層做些監控和日誌管理,將 SSO 登錄集成進 Node 層,使用 PM2 對 Node 做多進程管理。這樣之後,後端項目就可以做成」微服務」式的架構。

從前端項目工程化管理的角度來看,後端項目」微服務」式架構有如下優勢:

前端只與 Node 中間層進行數據通信,Node 層則通過 thrift 接口與後端服務進行數據通信;Node 中間層的 API 設計遵循 RESTFul 的架構風格,並且都以 /api/* 做為前綴;Node 中間層可以視情況添加緩存服務

三、前端工程化

現代化的前端開發已經不僅僅是業務代碼本身,而是涉及了很多方面的需求,比如:開發需求、共享需求、性能需求、部署需求。

3.1 開發需求

如果是新團隊,在開始一個前端項目時,我們會先進行技術選型,然後定義代碼規範,再根據業務模塊拆分進行項目目錄規劃,這些相關的需求都算作前端開發需求。

如果在成熟團隊中,可能已經有技術沉澱了,怎麼去優化和改進以及文檔化就成為我們需要去琢磨的事了。

代碼規範

ESLint是一個用來識別 ECMAScript 並且按照規則給出報告的代碼檢測工具,使用它可以避免低級錯誤和統一代碼的風格。

我們可以方便的在配置文件中配置自己想要的風格規範,通常推薦使用Airbnb JavaScript或者google的規範。

CSS預處理

我們可以使用 less 或 sass 來優化 css 的開發過程,而如果考慮到瀏覽器兼容性的hack問題,我們可以用 postcss 作為預處理工具幫我們自動解決這些 hack。

熱更新

hmr能夠在感知你的代碼有變動的情況下自動調用編譯工具編譯源碼,然後通過 livereload 自動刷新瀏覽器,這樣做的話能節省你的調試時間。

Mock

由於採用了前後端分離的開發模式,在真實開發中,為了讓前端開發不受後端進度的影響,我們需要對數據進行 mock。

前後端先約定 API 接口定義,然後前端根據定義 mock 接口。

一般大公司會有自己的 mock 平臺,小公司如果沒有的話也可以使用開源的mock工具。

3.2 共享需求

對於公司而言,快速高效地實現業務是終極目標,這對前後端來說都是挑戰。在前端團隊中,能夠形成基礎組件庫和業務組件庫是一種必然需求。

所以在設計前端項目架構的時候,一定要考慮業務的組件化和可共享性。有人說開發通用組件是造輪子,其實造出符合自己的輪子何嘗不是一種領悟。

共享需求主要有四種:基礎代碼共享、通用工具方法共享、基礎交互組件共享以及業務組件共享。

在組件方面,React 提供了天然的組件結構,我們只需要在開發過程中,隱藏組件的內部實現,每個組件更獨立,很容易形成可重用組件。

3.3 性能需求

如何對 web 資源的加載速度進行優化呢?

JS/CSS 代碼壓縮

JS/CSS 代碼合併

圖片壓縮

CSS 圖片精靈或雪碧圖

這些過程都可以在前端工程的構建過程中使用 Grunt/Gulp、webpack 等構建工具實現。

3.4 部署需求

前端工程通常是由多人維護的,所以會用代碼管理工具來管理源碼,然後將開發流程和部署流程與 git 結合起來。多人分支協作流程:用 git flow 來管理代碼分支。

四、總結

實踐證明,圍繞著 React 所建立起來的生態系統以及組件化開發思想能有效地分解大規模應用的複雜度、提高資源復用率。簡單的說,React 擁有以下你想要的特性:

當然,使用React也有一些缺點,例如頁面 javascript 文件體積動輒上百KB,這就限制了在移動端項目上的使用。

我們可以通過一些離線化方案,例如使用 LocalStorage 緩存等來儘量的減少對大體積靜態資源的請求。

總的來說,React 的生態系統大而全,如果沒有涵蓋的部分,還請海涵。僅此與各位 dalao 共享一些個人觀點,共同進步。

彩蛋

重磅 Chat

一場 Chat 讓你搞清 BAT 程式設計師的技術職級

分享人: 

勝洪宇,一線網際網路公司前端技術組長,掘金籤約作者,前端博客博主,所講課程幫助超過20萬前端小夥伴學習。

Chat簡介:

很多程式設計師嚮往進入 BAT 這樣的大型網際網路公司,但是又不知道他們如何評定技術職級。

阿里集團薪資職級如何劃分?讓你快速得到馬雲的青睞。

在百度明白這些,你將快速晉升。

騰訊職級裡的小秘密,這樣工作你會更強。

一場 Chat 讓你搞清 BAT 的技術評價體系,為您進入超級網際網路公司指明技術方向,時刻做好準備!如果您希望您的技術團隊也像這些網際網路巨頭一樣強大,本場 Chat 我將幫您馬上模仿建立有效的技術職級體系。

想要免費參與本場 Chat ?

關注「GitChat 技術雜談」公眾號

並在後臺回復BAT

👇

「閱讀原文」查看 本次Chat交流實錄

相關焦點

  • 「首席架構師推薦」關於React生態系統的一系列精選資源(2)
    - 具有自然和確定性價值的設計系統blueprint - 基於React的Web工具包office-ui-fabric-react - 用於構建Microsoft Web體驗的React組件react-bootstrap - 使用React構建的Bootstrap組件reactstrap - 簡單的React Bootstrap 4組件semantic-ui-react - 官方的Semantic-UI-React
  • 「首席架構師推薦」關於React生態系統的一系列精選資源(3)
    reactn - React,但內置全局狀態管理immer - 通過改變當前狀態來創建下一個不可變狀態地圖react-googlemaps - 反映Google地圖的界面react-maps - React的映射組件react-google-maps - React.js Google Maps集成組件react-gmaps - React.js的Google Maps組件react-map-gl
  • Facebook 發布 React Native for Android
    React Native 支持標準平臺組件的使用,比如 iOS 的 UITabBar 和 Anroid 的 Drawer 組件,因此可以提供跨平臺生態系統的統一外觀和感覺。這些平臺組件可以使用 React 組件接口集成到一個應用,比如 TabBarIOS 和 DrawerLayoutAndroid。
  • React Native 0.63 發布,告警系統、顏色與交互能力改進
    API默認啟用 LogBox社區一直以來反饋錯誤和警告很難在 React Native 中進行調試,因此開發團隊研究了 React Native 中的整個錯誤、警告和日誌系統,從頭開始對其進行了重新設計,現在使用一個新系統 LogBox 替換 redbox、yellowbox 與日誌記錄。
  • 十大最受歡迎的 React Native 應用開發編輯器
    /跨平臺編輯內置包管理器智能自動補全文件系統瀏覽器多個窗格查找和替換Atom 是一款現代化、易用、可控的文本編輯器。Sublime Text 常用包react-native-snippets - 用於 react native 的 Sublime Text 的片段集合babel-sublime - 具有 React JSX 擴展的 ES6 JavaScript 的語法定義。4.
  • React + Redux + React-router 全家桶
    web端開發需要搭配React-dom使用import React from 'react';import ReactDOM from 'react-dom';const App = () => (  <div>      <
  • react腳手架create-react-app入門
    記得關注,每天都在分享不同知識不管是哪個前端框架都支持快速開發,通過腳手架可以讓咱們更便捷的構建項目,無需考慮搭建環境問題,今天來聊聊create-react-app腳手架安裝腳手架>npm install -g create-react-app創建項目create-react-app myapp # myapp是項目的名稱,這樣就會在當前目錄生成一個myapp的項目
  • React Status 中文周刊 #18 - 三種 React 的反面模式
    🔥 本周熱門Reactochart:由 Spotify 推出的 react 圖表庫 — 此圖表庫由 Spotify 推出,目前已在線上穩定運行了很長時間,同時擁有友好的文檔,每種類型的圖表(折線,條形圖,餅圖,直方圖,熱圖等)都有對應的 demo 參考。
  • React Status 中文周刊 #8 - 100 行代碼實現 Facebook 的 Recoil React 庫
    Yoav Niran🔧 代碼和工具react-range: 支持可訪問性的滑動輸入條 Vojtech Miksureact-async-hook: 在組件中處理異步操作 —InfluxDatareact-filepond:  文件上傳組件 — Filepond
  • 【重學React】動手實現一個react-redux
    react-redux 是什麼react-redux 是 redux 官方 React 綁定庫。它幫助我們連接UI層和數據層。本文目的不是介紹 react-redux 的使用,而是要動手實現一個簡易的 react-redux,希望能夠對你有所幫助。
  • 《React 學習之道》中文版
    有興趣的可以通過下方地址下載或閱讀https://leanpub.com/the-road-to-learn-react-chinese/最後,為你推薦【第1167期】npm 2017 JavaScript 框架報告之 React 生態系統分析【第1163期】React 整潔代碼最佳實踐關於本文
  • 前端技術:React&Vue對比
    React和vue的業務邏輯是差不多,vue在react上封裝了更簡潔的方法,使用起來更加的便捷,如:提供了便捷的指令(v-for,v-if,v-model),還提供了更多的屬性(computed,watch),我還是比較喜歡用react的,更接近js原生,更容易於理解它。
  • React 16.8 之 React Hook
    有了 react hook 就不用寫class(類)了,組件都可以用function來寫,不用再寫生命周期鉤子,最關鍵的,不用再面對this了!Hook 規則hook本質也是javaScript函數,但是他在使用的時候需要遵循兩條規則,並且react要求強制執行這兩條規則,不然就會出現奇怪的bug。
  • 30 分鐘精通 React 新特性——React Hooks
    如果你也對react感興趣,或者正在使用react進行項目開發,答應我,請一定抽出至少30分鐘的時間來閱讀本文好嗎?所有你需要了解的React Hooks的知識點,本文都涉及到了,相信完整讀完後你一定會有所收穫。
  • React Status 中文周刊 #7 - 使用 React 仿寫 TikTok
    Mateusz Podlasinreactjs-popup:一個簡單的 React Popup 組件Harry Herskowitz▶  在 JavaScript/CSS/React 中檢測系統主題Facebookreact-use-pip:畫中畫功能的 React Hooks — 有人可能把
  • React Status 中文周刊 #26 - Aleph:基於 Deno 的 React 框架
    新年將近,提前預祝大家新年快樂~電腦閱讀,請訪問 https://docschina.org/weekly/react🔥 本周熱門基於 AWS Lambda 的 React 應用服務端渲染 — 通過使用 Lambda 或 Lambda@Edge
  • 掌握react,這一篇就夠了
    react眾所周知的前端3大主流框架之一,由於出色的性能,完善的周邊設施風頭一時無兩。本文就帶大家一起掌握react。
  • React Status 中文周刊 #21 - 2020 年 React 大事記回顧
    原文連結:https://www.robinwieruch.de/react-librariesRobin Wieruch原文連結:https://www.lorenzweiss.de/common_mistakes_react_hooks/Lorenz
  • ReactNative 的組件架構設計
    todo 一個問題:由於 react 是面向狀態編程,相當於 react 的組件只關注數據的最終狀態,數據是怎麼產生的並不關心,但是某些場景下,數據如何產生的是會影響到組件的一些行為的【比如一個新增行要求有動畫效果,查詢出的行就不需要等】,這在 RN 中很難描述。。。。。
  • React系列教程
    本課程就讓我們從無到有,一點一滴的系統的學習React.JS,逐漸的成為一名React.JS的使用高手。大綱列表:第一講:初識React.JS1.什麼是React?2.腳手架的介紹3.認識React的腳手架 - create-react-app4.腳手架的環境的下載及使用5.腳手架內部的基本構成介紹6.使用腳手架製作圖片展示組件 第十三講:React的動畫1.React動畫的基本使用2.React的動畫插件 - react-transition-group