React 入門 (基礎概念)
前言
準備寫這篇文章時,才發現一年都沒有總結了。之前還想一個月總結一次,對比現在簡直太誇張了。其實今年的收穫還挺多的,比如將學習的python、react應用到工作中,個人爬蟲網站上線。
開始的時候我是很牴觸的,因為覺得後端寫前端最後肯定會不三不四,之前也寫過前後端全包的專案,但是對後面的工作都沒什麼幫助,所以覺得對個人發展也不是很好,而且全棧工程師在杭州需求也不多。沒辦法,公司就是不給配前端,只能一個人整,想想不能影響專案進度啊,最後倒黴還是自己,所以硬著頭皮跳下去了。
專案大概做了4個月,對前端其實還是皮毛,但是完成專案需求還是搓搓有餘。能撐到現在是因為有個念頭:往全棧工程師發展也不一定是件壞事,說不定就有奇蹟了呢。
簡介
React.js 是一個幫助你構建頁面 UI 的庫。如果你熟悉 MVC 概念的話,那麼 React 的元件就相當於 MVC 裡面的 View。說白點就是幫助我們將介面分成各個獨立的小塊,每一個塊就是元件,這些元件之間可以組合、巢狀,就成了我們的頁面。
一個元件的顯示形態和行為有可能是由某些資料決定的。而資料是可能發生改變的,這時候元件的顯示形態就會發生相應的改變。而 React.js 也提供了一種非常高效的方式幫助我們做到了資料和元件顯示形態之間的同步。
React.js 不是一個框架,它只是一個庫。它只提供 UI (view)層面的解決方案。在實際的專案當中,它並不能解決我們所有的問題,需要結合其它的庫,例如 Redux、React-router 等來協助提供完整的解決方法。
JSX
React的核心機制就是實現了一個虛擬DOM,利用虛擬DOM來減少對實際DOM的操作從而提升效能,元件DOM結構就是對映到這個虛擬的DOM上,React在這個虛擬DOM上實現了一個diff演算法,當要更新元件的時候,會通過diff尋找要變更的DOM節點,再把這個修改更新到瀏覽器實際的DOM節點上,所以實際上不是真的渲染整個DOM樹,這個虛擬的DOM是一個純粹的JS資料結構,所以效能比原生DOM會提高很多;
虛擬DOM(virtual-dom)實際上是對實際DOM的一個抽象,是一個js物件。react所有的表層操作實際上是在操作虛擬DOM。經過diff演算法計算出虛擬DOM的差異,然後將這些差異進行實際的DOM操作更新頁面
從 JSX 到頁面經歷的過程:
- JSX 是 JavaScript 語言的一種語法擴充套件,長得像 HTML,但並不是 HTML。
- React.js 可以用 JSX 來描述你的元件長什麼樣的。
- JSX 在編譯的時候會變成相應的 JavaScript 物件描述。
- react-dom 負責把這個用來描述 UI 資訊的 JavaScript 物件變成 DOM 元素,並且渲染到頁面上。
元件化
虛擬DOM(virtual-dom)不僅帶來了簡單的UI開發邏輯,同時也帶來了元件化開發的思想,所謂元件,即封裝起來的具有獨立功能的UI部件。React推薦以元件的方式去重新思考UI構成,將UI上每一個功能相對獨立的模組定義成元件,然後將小的元件通過組合或者巢狀的方式構成大的元件,最終完成整體UI的構建。
可以按照下面的規則進行劃分元件:
-
容器元件:容器型元件是一個頁面容器,用來放置當前頁面的所有展示型元件和業務元件組合成一個頁面,通過資料的驅動進行控制展示元件和業務元件。
-
展示元件:展示型元件是具體到某一個小的元件模組,比如一個按鈕,一個卡片,一個進度條等,我們在用react做元件化開發的時候,先定義好一個個小的展示型元件,然後把這些元件都匯入容器型元件,最終組合成一個完整的頁面。
-
業務元件:頁面中某個業務模組的拆分,涉及到資料互動,有自己獨立的業務邏輯
React 認為一個元件應該具有如下特徵:
- 可組合(Composeable):一個元件易於和其它元件一起使用,或者巢狀在另一個元件內部。如果一個元件內部建立了另一個元件,那麼說父元件擁有(own)它建立的子元件,通過這個特性,一個複雜的UI可以拆分成多個簡單的UI元件。
- 可重用(Reusable):每個元件都是具有獨立功能的,它可以被使用在多個UI場景。
- 可維護(Maintainable):每個小的元件僅僅包含自身的邏輯,更容易被理解和維護。
元件種類
function-based(函式元件):函式元件也稱為無狀態元件,使用純函式建立,建立後不會產生元件例項,也就是說無法使用ref獲取,主要用於展示元件的開發,效能高,沒有生命週期,沒有state,但是可以接收props,相當於一個只有render生命週期的元件
function Component (props) { return <div>{props.children}</div> } //使用 <Component>元件</Component>
class-based(類元件):使用es6 class的方式建立,通過繼承React.component實現,可以有自己獨立的生命週期,state狀態,必須有render生命週期,state定義在constructor建構函式中,所用的容器元件都是通過class建立
class Component extends React.component { constructor (props) { super(props) this.state = { age: 100 } } render () { const {age} = this.state return <div>{age}</div> } } //使用 <Component />
createClass元件:不常用
在react中最小的單位是元素,元素分為dom元素,元件元素,區分方法是dom元素小寫,元件元素首字母大寫
元件狀態
每個元件都有一個狀態,下面幾點僅適用於class-based元件。
一個元件的顯示形態是可以由它資料狀態和配置引數決定的。在react中元件的狀態使用state定義,使用setState修改,使用this.state讀取。
setState
setState
方法由父類 Component 所提供。當我們呼叫這個函式的時候,React.js 會更新元件的狀態 state ,並且重新呼叫 render 方法,然後再把 render 方法所渲染的最新的內容顯示到頁面上。
setState
是“非同步”的,呼叫 setState
只會提交一次state修改到佇列中,不會直接修改 this.state
。等到滿足一定條件時,react會合並佇列中的所有修改,觸發一次update流程,更新 this.state
。因此setState機制減少了update流程的觸發次數,從而提高了效能。
setState
的更新是一個淺合併(Shallow Merge)的過程
特殊情況:
在實際開發中,setState的表現有時會不同於理想情況。主要是以下兩種:
- 在mount流程中呼叫setState。
- 在setTimeout/Promise回撥中呼叫setState。
在第一種情況下,不會進入update流程,佇列在mount時合併修改並render。
在第二種情況下,setState將不會進行佇列的批更新,而是直接觸發一次update流程。這是由於setState的兩種更新機制導致的,只有在批量更新模式中,才會是“非同步”的。
State 與 Props 區別
state
的主要作用是用於元件儲存、控制、修改自己的可變狀態。state 在元件內部初始化,可以被元件自身修改,而外部不能訪問也不能修改。你可以認為 state 是一個區域性的、只能被元件自身控制的資料來源。state 中狀態可以通過 this.setState 方法進行更新,setState 會導致元件的重新渲染。
props
的主要作用是讓使用該元件的父元件可以傳入引數來配置該元件。它是外部傳進來的配置引數,元件內部無法控制也無法修改。除非外部元件主動傳入新的 props,否則元件的 props 永遠保持不變。
state 是讓元件控制自己的狀態,props 是讓外部對元件自己進行配置
元件的生命週期
對於 React 元件來說,生命週期主要包含三個階段:建立(掛載)過程、銷燬(解除安裝)過程和存在期。
React.js 將元件渲染,並且構造 DOM 元素然後塞入頁面的過程稱為元件的掛載。過程如下:
-> constructor() -> componentWillMount() -> render() // 然後構造 DOM 元素插入頁面 -> componentDidMount()
componentWillMount
和 componentDidMount
都是可以像 render 方法一樣自定義在元件的內部。掛載的時候,React.js 會在元件的 render 之前呼叫 componentWillMount
,在 DOM 元素塞入頁面以後呼叫 componentDidMount
。
一個元件可以插入頁面,當然也可以從頁面中刪除
-> constructor() -> componentWillMount() -> render() // 然後構造 DOM 元素插入頁面 -> componentDidMount() // ... // 即將從頁面中刪除 -> componentWillUnmount() // 從頁面中刪除
setState更新機制大致流程:
componentWillReceiveProps shouldComponentUpdate shouldComponentUpdate componentWillUpdate componentDidUpdate
可以將 React
視為我們聘請的與瀏覽器通訊的代理。我們不是去手動的用DOM API來操作DOM,而是更元件狀態的屬性值,然後讓 React
代表我們去和瀏覽器溝通. 我相信著就是react為什麼這麼受歡迎的原因. 我們討厭和瀏覽器先生(還說著各種帶有口音的DOM方言)打交道,React志願為我們做這些事情,還是免費的~
小結
- React速度很快
與其它框架相比,React採取了一種特立獨行的操作DOM的方式。 它並不直接對DOM進行操作。
它引入了一個叫做虛擬DOM的概念,安插在JavaScript邏輯和實際的DOM之間。
這一概念提高了Web效能。在UI渲染過程中,React通過在虛擬DOM中的微操作來實對現實際DOM的區域性更新。
- 跨瀏覽器相容
虛擬DOM幫助我們解決了跨瀏覽器問題,它為我們提供了標準化的API,甚至在IE8中都是沒問題的。
- 模組化
為你程式編寫獨立的模組化UI元件,這樣當某個或某些元件出現問題是,可以方便地進行隔離。
每個元件都可以進行獨立的開發和測試,並且它們可以引入其它元件。這等同於提高了程式碼的可維護性。
- React與其它框架/庫相容性好
比如使用RequireJS來載入和打包,而Browserify和Webpack適用於構建大型應用。它們使得那些艱難的任務不再讓人望而生畏。
缺點:
React本身只是一個V而已,所以如果是大型專案想要一套完整的框架的話,還需要引入Flux和routing相關的東西